Audio Recording in Linux

Source: Internet
Author: User

I. Principles

In Linux, recording-reads data from the dsp device and playing-writes data to the dsp device.

The Development Board uses the sound card UDA1341 to implement audio codec and complete A/D and D/A conversion. The figure below shows the connection between the chip UDA1341 and the CPU:

 

To achieve full duplex, two DMA channels are required for data transmission. Taking audio playback as an example, data transmission is first sent from the internal bus to the memory, then to DMA controller Channel 1, and then written to the IIS bus through the IIS controller and transmitted to the audio chip. Channel 2 is used for recording.

Ii. WAV files

WAVE is the standard Windows file format used for recording. The file extension is"WavThe data format is PCM or compressed, which is one of the lossless music formats.RIFF(Resource Interchange File Format) specification. All WAV Files have a file header, which is the encoding parameter of the audio stream. The data block record method isLittle-endian byte order, The flag is not a string but a separate symbol.

ToThe sampling rate is 8 kHz, the quantizing digits are 16, and the Single ChannelFor example, the first three lines of the record.wav file are as follows:

The first column indicates the address, and one row indicates 16 bytes.

0x46 // ASCII value corresponding to four characters of "RIFF"

0 x, 0 x, 0 x, 0 x, 0x66, 0x6D, 0x20 // ASCII value corresponding to each character of "WAVEfmt"

0 x, 0 x, 0 x, 0 x, 0 x, 0 x, 0 x, 0x00 // sizeof (PCMWAVEFORMAT) 4 Byte, format Category 2B, number of channels 1B (Channel)

0x40, 0x1F, 0x8000, 0 x, 0x80, 0x3E, 0 x, 0x00, // sampling frequency 0X0001F40 = 8 kHZ (Hz) 4B, 0x00003E80B/s = 16kB/s 4B

0x0002x16/8, 0 x, 0 x, 0x64, 0 x, 0 x, 0x61}; // data adjustment count 0x(1 *) 2B, that is, the number of bytes occupied by a sampling point. The number of digits of the sample data is 0x10 (16 bits) 2B, that is, the number of BITs represented by a sampling point is "data" 4B.

Address range: 14h ~ 000017H value: 2400 01 00, that is, hexadecimal 0x00010024, corresponding to decimal 65572 (65536 +36) Indicates the total number of bytes from 0x08 to the end of the file;

Address limit 28h ~ 00002BH value: 0080 0C 00, that is, hexadecimal 0x00010000, corresponding to decimal 65536, indicates the total number of sampled data.

Recording test command: cat/dev/sound/dsp> audio.wav

The audio.wav generated using the catcommand is a PCM pure audio file:

You can add a wav file header to generate a standard wav audio file:

3. Enable recording and releasing in Linux

Note the default parameters in the driver. The application can use the ioctl () function to set new values.

 

Open () function: You must specify the mode used to operate the sound card when you Open the device. For sound cards that do not support full duplex, you should Open them in read-only or write-only mode, only sound cards that support full duplex can be opened in read/write mode, which depends on the specific implementation of the driver. Open_mode has three options: O_RDONLY, O_WRONLY, and O_RDWR, which indicate read-only, write-only, and read-write respectively.OSS recommends that you use read-only or write-only mode whenever possible. The read/write mode is used only in full-duplex scenarios (that is, when both recording and sound recording are performed.Linux allows applications to open or close the device file corresponding to the sound card multiple times, so that switching between the sound recording status and the recording status is convenient.

Note that you must always read/write a complete sample. For example, in a 16-bit stereo mode, each sample has 4 bytes, so the application must read/write multiple bytes of 4 at a time.

The source code is as follows:

 

# Include <unistd. h> # include <fcntl. h> # include <sys/types. h> # include <sys/ioctl. h> # include <stdlib. h> # include <stdio. h> # include <linux/soundcard. h> # define LENGTH 3 // storage seconds # define RATE 44100 // sampling frequency # define SIZE 16 // quantified digits # define CHANNELS 2 // number of audio CHANNELS/* used to save Digital Audio data memory buffer */unsigned charbuf [LENGTH * RATE * SIZE * CHANNELS/8]; int main () {intfd; // file descriptor intarg of the sound device; // intstatus parameter used for ioctl call; // return value of the system call/* enable the sound device */fd = Open ("/dev/sound/dsp", O_RDONLY); if (fd <0) {perror ("openof/dev/sound/dsp failed "); exit (1);}/* set the quantified number of digits during sampling */arg = SIZE; status = ioctl (fd, SOUND_PCM_WRITE_BITS, & arg); if (status =-1) perror ("SOUND_PCM_WRITE_BITSioctl failed"); if (arg! = SIZE) perror ("unableto set sample size");/* set the number of audio CHANNELS during sampling */arg = CHANNELS; status = ioctl (fd, SNDCTL_DSP_STEREO, & arg ); if (status =-1) perror ("SNDCTL_DSP_STEREOioctl failed"); if (arg! = CHANNELS) perror ("unableto set number of channels");/* set the sampling frequency when sampling */arg = RATE; status = ioctl (fd, SNDCTL_DSP_SPEED, & arg ); if (status =-1) perror ("SNDCTL_DSP_SPEEDioctl failed"); if (arg! = RATE) perror ("unableto set rate"); printf ("Saysomething: \ n"); status = read (fd, buf, sizeof (buf )); // recording if (status! = Sizeof (buf) perror ("readwrong number of bytes"); printf ("Yousaid: \ n"); close (fd ); fd = open ("/dev/sound/dsp", O_WRONLY); if (fd <0) {perror ("openof/dev/sound/dsp failed "); exit (1);}/* set the quantified number of digits during sampling */arg = SIZE; status = ioctl (fd, SOUND_PCM_WRITE_BITS, & arg); if (status =-1) perror ("SOUND_PCM_WRITE_BITS ioctl failed"); if (arg! = SIZE) perror ("unable toset sample size");/* set the number of audio CHANNELS during sampling */arg = CHANNELS; status = ioctl (fd, SNDCTL_DSP_STEREO, & arg ); if (status =-1) perror ("SNDCTL_DSP_STEREO ioctl failed"); if (arg! = CHANNELS) perror ("unable toset number of channels");/* set the sampling frequency */arg = RATE; status = ioctl (fd, SNDCTL_DSP_SPEED, & arg ); if (status =-1) perror ("SNDCTL_DSP_SPEED ioctl failed"); if (arg! = RATE) perror ("unable toset rate"); status = write (fd, buf, sizeof (buf); // playing if (status! = Sizeof (buf) perror ("wrotewrong number of bytes"); close (fd); return0 ;}

Note in the program is the parameter settings of the open () function. The O_RDWR parameter is used before, and errors always occur when the sound is played. The specific cause of the error may be related to the driver settings. In this design, the correct setting is to select O_RDONLY for recording and O_WRONLY for playing.

 

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.