OSS audio interface programming in Linux

Source: Internet
Author: User
OSS audio interface programming in Linux-general Linux technology-Linux programming and kernel information. For details, refer to the following section.
CODE :/*
Name: SndKit. c
Copyright: GPLv2
Author: rockins (ybc2084@163.com)
Date: 15-10-06
Description: implent raw sound record/play
Run :. /SndKit [-h] [-d device] [-c channel] [-B bits] [-f hz] [-l len] <-r |-p file>
E.g .:
./SndKit-h show help information
./SndKit-r record.wav record audio from microphone (/dev/dsp)
./SndKit-d/dev/dsp-p record.wav playback record.wav via/dev/dsp
./SndKit-B 8-f 22-r reacord.wav record audio in 8 bit & 22 k hz
./SndKit-d/dev/dsp-c 2-r record.wav record audio in/dev/dsp and stereo
./SndKit-r-l 40 record.wav record 40 k audio data
*/
# Include
# Include
# Include
# Include
# Include
# Include
# Include /* For OSS style sound programing */
# Define TRUE 1
# Define FALSE 0
# Define FMT8BITS AFMT_U8/* unsigned 8 bits (for almost PC )*/
# Define FMT16BITS AFMT_S16_LE/* signed 16 bits, little endian */
# Define fmt8 K 8000/* default sampling rate */
# Define FMT11K 11025/* 11,22, 44,48 are three pop rate */
# Define FMT22K 22050
# Define FMT44K 44100
# Define FMT48K 48000
# Define MONO 1
# Define STEREO 2
# Define ACT_RECORD 0
# Define ACT_PLAY 1
# Define DFT_SND_DEV "/dev/dsp"
# Define DFT_SND_FMT FMT8BITS
# Define DFT_SND_SPD FMT8K
# Define DFT_SND_CHN MONO
# Define DFT_LEN 1024/* default record length: 40 k */
# Define BUFF_SIZE 512/* buffer size: 512 Bytes */
/************** Function prototype ********************/
Void Usage (void );
Int OpenDevice (const char *, unsigned int );
Int OpenFile (const char *, unsigned int );
Int CloseDevice (unsigned int );
Int CloseFile (unsigned int );
/************* Function implementation **************/
Int main (int argc, char * argv [])
{
Unsigned int snd_fmt = DFT_SND_FMT;/* sound format, bits */
Unsigned int snd_chn = DFT_SND_CHN;/* sound channel number */
Unsigned int snd_spd = DFT_SND_SPD;/* sound speed, frequency */
Unsigned char * s_file = NULL;/* file hold sound data */
Unsigned char * snd_device = DFT_SND_DEV;/* sound device */
Unsigned int recd_or_play = ACT_PLAY;/* flag (default play )*/
Unsigned char buff [BUFF_SIZE];/* sound buffer */
Unsigned long len = DFT_LEN * 1024;/* record or play length (k )*/
Int snd_fd;/* sound device descriptor */
Int s_fd;/* sound data file descrit */
Ssize_t n;/* bytes already in or out */
Ssize_t nRD;/* bytes readin */
Ssize_t nWR;/* bytes write out */
Unsigned int opt_chr;/* hold cli option */
Unsigned int opt_err = FALSE;/* indicate whether parse option error */
/* Parse cli option via getopt routine */
Optind = 0;/* set optindex to 0 */
While (opt_chr = getopt (argc, argv, "hd: c: B: f: l: r: p :"))! =-1 ){
Switch (opt_chr ){
Case 'H ':
Usage ();
Return (0);/* return, 0 denote success */
Break;
Case 'D ':
Snd_device = optarg;/* sound device name */
Break;
Case 'C ':
If (atoi (optarg) = 1)/* select channel number */
Snd_chn = MONO;
Else if (atoi (optarg) = 2)
Snd_chn = STEREO;
Else {
Opt_err = 1;/* error occur */
Fprintf (stderr, "wrong channel setting ,"
"Shoshould be 1 or 2 (default 1, MONO) \ n ");
}
Break;
Case 'B ':
If (atoi (optarg) = 8)/* select data bit */
Snd_fmt = FMT8BITS;
Else if (atoi (optarg) = 16)
Snd_fmt = FMT16BITS;
Else {
Opt_err = 1;/* error occur */
Fprintf (stderr, "wrong bits setting ,"
"Shocould be 8 or 16 (default 8) \ n ");
}
Break;
Case 'F ':
If (atoi (optarg) = 8)
Snd_spd = FMT8K;/* sampling rate: 8 kbps */
Else if (atoi (optarg) = 11)
Snd_spd = FMT11K;/* smapling rate: 11.025 k */
Else if (atoi (optarg) = 22)
Snd_spd = FMT22K;/* sampling rate: 22.050 k */
Else if (atoi (optarg) = 44)
Snd_spd = FMT44K;/* sampling rate: 44.100 k */
Else if (atoi (optarg) = 48)
Snd_spd = FMT48K;/* sampling rate: 48 k */
Else {
Opt_err = 1;/* error occur */
Fprintf (stderr, "wrong sampling rate ,"
"Shoshould be 8, 11, 22, or 44 (default 8 kbps) \ n ");
}
Break;
Case 'l ':
Len = atoi (optarg) * 1024;/* record length (k )*/
Break;
Case 'r ':
Recd_or_play = ACT_RECORD;
S_file = optarg;/* file to record sound */
Break;
Case 'p ':
Recd_or_play = ACT_PLAY;
S_file = optarg;/* file to play sound */
Break;
Case '? ':
Opt_err = 1;
Fprintf (stderr, "unknown option: % c \ n", optopt );
Break;
Default:
Opt_err = 1;
Fprintf (stderr, "getopt error: % d \ n", opterr );
Break;
}
}
/* Check if cli option parsed right */
If (opt_err | argc <2 ){
Fprintf (stderr, "parse command option failed !!! \ N"
"Run./SndKit-h for help \ n ");
Return (-1 );
}
/* Open device */
If (snd_fd = OpenDevice (snd_device, recd_or_play) <0 ){
Fprintf (stderr, "cannot open device % s: % s \ n", snd_device,
Strerror (errno ));
Return (-1 );
}
/* Open sound data file */
If (s_fd = OpenFile (s_file, recd_or_play) <0 ){
Fprintf (stderr, "cannot open sound file % s: % s \ n", s_file,
Strerror (errno ));
Return (-1 );
}
/* Set sound format */
If (SetFormat (snd_fd, snd_fmt, snd_chn, snd_spd) <0 ){
Fprintf (stderr, "cannot set % s in bit % d, channel % d, speed % d \ n ",
Snd_device, snd_fmt, snd_chn, snd_spd );
Return (-1 );
}
/* Do real action: record or playback */
If (recd_or_play = ACT_RECORD) {/* record sound into data file */
N = 0;
While (n <len ){
NRD = 0;/* amount read from sound device */
If (nRD = read (snd_fd, buff, BUFF_SIZE) <0 ){
Perror ("read sound device failed ");
Return (-1 );
}
If (n + nRD <= len)/* the len is not full */
NWR = nRD;/* write amount to sound data file */
Else
NWR = len-n;/* len will be overflow */
Unsigned long old_nWR = nWR;/* s hold nWR's old value */
Unsigned long t = 0L;/* temp counter */

While (nWR> 0 ){
If (t = write (s_fd, buff, nWR) <0 ){
Perror ("write sound data file failed ");
Return (-1 );
}
NWR-= t;
}
N + = old_nWR;
}
} Else if (recd_or_play = ACT_PLAY) {/* write sound data to device */
While (TRUE ){
NRD = 0L;/* read amount from sound device */
If (nRD = read (s_fd, buff, BUFF_SIZE) <0 ){
Perror ("read sound data file failed ");
Return (-1 );
} Else if (nRD = 0) {/* nRD = 0 means all sound stream output */
Printf ("sound data play complete! \ N ");
Exit (0 );
}
NWR = nRD;
While (nWR> 0) {/* write into device */
If (n = write (snd_fd, buff, nWR) <0 ){
Perror ("write sound device file failed ");
Return (-1 );
}
NWR-= n;
}
}
}
/* Close the sound device and sound data file */
CloseDevice (snd_fd );
CloseFile (s_fd );
Return (0 );
}
/*
* OpenDevice (): open sound device
* Params:
* Dev_name -- device name, such as/dev/dsp
* Flag -- flag (ACT_RECORD or ACT_PLAY)
* Returns:
* File descriptor of sound device if sucess
*-1 if failed
*/
Int OpenDevice (const char * dev_name, unsigned int flag)
{
Int dev_fd;
/* Open sound device */
If (flag = ACT_RECORD ){
If (dev_fd = open (dev_name, O_RDONLY) <0 ){
Return (-1 );
}
} Else if (flag = ACT_PLAY ){
If (dev_fd = open (dev_name, O_WRONLY) <0 ){
Return (-1 );
}
}
Return (dev_fd );
}
/*
* CloseDevice (): close the sound device
* Params:
* Dev_fd -- the sound device's file descriptor
* Returns:
* 0 if success
*-1 if error occured
*/
Int CloseDevice (unsigned int dev_fd)
{
Return (close (dev_fd ));
}
/*
* OpenFile (): open sound data file
* Params:
* File_name -- file name,e.g,record.wav
* Flag -- flag (ACT_RECORD or ACT_PLAY)
* Returns:
* File descriptor of sound data file if sucess
*-1 if failed
*/
Int OpenFile (const char * file_name, unsigned int flag)
{
Int file_fd;
/* Open sound data file */
If (flag = ACT_RECORD ){
If (file_fd = open (file_name, O_WRONLY) <0 ){
Return (-1 );
}
} Else if (flag = ACT_PLAY ){
If (file_fd = open (file_name, O_RDONLY) <0 ){
Return (-1 );
}
}
Return (file_fd );
}
/*
* CloseFile (): close the sound data file
* Params:
* File_fd -- the sound data file's descriptor
* Returns:
* 0 if success
*-1 if error occured
*/
Int CloseFile (unsigned int file_fd)
{
Return (close (file_fd ));
}
/*
* SetFormat (): Set Record and Playback format
* Params;
* Fd -- device file descriptor
* Chn -- channel (MONO or STEREO)
* Bits -- FMT8BITS (8 bits), FMT16BITS (16 bits)
* Hz -- FMT8K (8000 HZ), FMT16K (16000 HZ), FMT22K (22000 HZ ),
* FMT44K (44000 HZ), FMT48K (48000 HZ)
* Returns:
* Return 0 if success, else return-1
* Notes:
* Parameter setting order shoshould be like:
* 1. sample format (number of bits)
* 2. number of channels (mono or stereo)
* 3. sampling rate (speed)
*/
Int SetFormat (unsigned int fd, unsigned int bits, unsigned int chn,
Unsigned int hz)
{
Int ioctl_val;
/* Set bit format */
Ioctl_val = bits;
If (ioctl (fd, SNDCTL_DSP_SETFMT, & ioctl_val) =-1 ){
Fprintf (stderr, "Set fmt to bit % d failed: % s \ n", bits,
Strerror (errno ));
Return (-1 );
}
If (ioctl_val! = Bits ){
Fprintf (stderr, "do not support bit % d, supported % d \ n", bits,
Ioctl_val );
Return (-1 );
}
/* Set channel */
Ioctl_val = chn;
If (ioctl (fd, SNDCTL_DSP_CHANNELS, & ioctl_val) =-1 ){
Fprintf (stderr, "Set Audio Channels % d failed: % s \ n", chn,
Strerror (errno ));
Return (-1 );
}
If (ioctl_val! = Chn ){
Fprintf (stderr, "do not support channel % d, supported % d \ n", chn,
Ioctl_val );
Return (-1 );
}
/* Set speed */
Ioctl_val = hz;
If (ioctl (fd, SNDCTL_DSP_SPEED, & ioctl_val) =-1 ){
Fprintf (stderr, "Set speed to % d failed: % s \ n", hz,
Strerror (errno ));
Return (-1 );
}
If (ioctl_val! = Hz ){
Fprintf (stderr, "do not support speed % d, supported is % d \ n", hz,
Ioctl_val );
Return (-1 );
}
Return (0 );
}
/*
* Usage (): print help information
* Params :( none)
* Returns :( none)
*/
Void Usage (void)
{
Printf
("Run :. /SndKit [-h] [-d device] [-c channel] [-B bits] [-f hz] [-l len] <-r |-p file> \ n"
"Description: implent raw sound record/play \ n" "option: \ n"
"\ T-h: print help informations \ n"
"\ T-d device: assign sound device to record or playback (default/dev/dsp) \ n"
"\ T-c channel: indicate in MONO or STEREO channel (default MONO) \ n"
"\ T-B bits: assign sampling bits depth (default 8 bits unsigned) \ n"
"\ T-f hz: indicate sampling rate, I. e, frequence (default 8 kbps) \ n"
"\ T-l len: indicate recording sound's length (default 1024 k) \ n"
"\ T-r |-p file: indicate record in or playback (no default, must give out explicitly) \ n"
"E.g.: \ n"
"\ T./SndKit-h show help information \ n"
"\ T./SndKit-r record.wav record audio from microphone (/dev/dsp) \ n"
"\ T./SndKit-d/dev/dsp-p record.wav playback record.wav via/dev/dsp \ n"
"\ T./SndKit-B 8-f 22-r reacord.wav record audio in 8 bit & 22 k hz \ n"
"\ T./SndKit-d/dev/dsp-c 2-r record.wav record audio in/dev/dsp and stereo \ n"
"\ T./SndKit-r-l 40 record.wav record 40 k audio data in record.wav \ n ");
}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.