Linux for audio playback

Source: Internet
Author: User

First, the principle of brief

Under Linux, recording--reading data from a DSP device, putting a sound--writes data to a DSP device.

The Development Board uses the sound card UDA1341 realizes the audio codec, completes A/D and D/a conversion, the chip UDA1341 and the CPU connection diagram are as follows:

To achieve full duplex, the data transfer requires two DMA channels. Take audio playback As an example, the data transfer is first sent by the internal bus to memory, then to the DMA Controller Channel 1, and then through the IIS controller written to the IIS bus and transmitted to the audio chip, channel 2 for recording.

Second, WAV file

Wave is the standard Windows file format used for recording, the file extension is "wav", the data itself is in the form of PCM or compression type, belonging to a lossless music format, in line with RIFF(Resource Interchange File Format) specification. All WAV has a file header, which is the encoding parameter of the header audio stream. Data blocks are recorded in small-ended (Little-endian) byte order , and the markers are not strings but separate symbols


Taking the sample rate of 8kHz, the quantization number of bits is 16, the single channel of the Record.wav file as an example, the first three lines of the file information is as follows:


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

0x52,0x49,0x46,0x46//"RIFF" 4 characters corresponding ASCII code value

0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20//"WAVEFMT" ASCII code value corresponding to each character

0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00//sizeof (Pcmwaveformat) 4Byte, Format category 2B, channel number 1B (channel)

0x40,0x1f,0x00,0x00,0x80,0x3e,0x00,0x00,//Sampling frequency 0x0001f40= 8kHZ (8000Hz) 4b,0x00003e80b/s=16kb/s 4 b

0x02,0x00,0x10,0x00,0x64,0x61,0x74,0x61};//Data Adjustment number 0x0002 (1*16/8) 2B, that is, the number of bytes of a sample point, sample Data bits 0x10 (16 bits) 2B, that is, the number of bits represented by a sample point " Data "4 b

The value of address 000014h~000017h: 2400 01 00 is the hexadecimal 0x00010024, corresponding to thedecimal 65572(65536+), which represents the total number of bytes from the beginning of the 0x08 to the end of the file;

Value of Address 000028H~00002BH: 0080 0C 00 is the hexadecimal 0x00010000, corresponding to the decimal 65536, which represents the total number of sampled data.

Recording test commands: CAT/DEV/SOUND/DSP > Audio.wav

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


By adding a WAV file header, you can generate a standard WAV audio file:


Third, the implementation of Linux playback sound

Note The default parameters in the driver, the application can set new values through the IOCTL () function.


Open () function: What mode to operate the sound card must also be specified when the device is turned on, for a sound card that does not support full duplex, should be opened in a read-only or write-only way, only those who support full-duplex sound card can be opened in a read-write manner, which also depends on the specific implementation of the driver. Open_mode has three options: O_rdonly,o_wronly and O_rdwr, which represent read-only, write-only, and read-write. OSS recommends using read-only or write-only, using read-write mode only when full-duplex (that is, recording and playback). Linux allows applications to turn on or off the device files corresponding to the sound card multiple times, making it easy to switch between the playback state and the recording state.

Note that the user always has to read/write a full sample. For example, in a 16-bit stereo mode, each sample has 4 bytes, so the application must read/write 4 times the number of bytes 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// Sample Frequency # define SIZE 16//Quantization digit # # CHANNELS 2///number of channels/* memory buffers */unsigned for storing digital audio data charbuf[length*rate*size*channels     /8];int Main () {intfd;    The file descriptor of the sound device intarg; Parameter Intstatus for the IOCTL call;                The return value of the system call/* Opens the sound device */fd= open ("/DEV/SOUND/DSP", o_rdonly);                        if (fd< 0) {perror ("OPENOF/DEV/SOUND/DSP failed");                Exit (1);                }/* Sets the number of quantization bits when 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 channels when 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 sampling frequency at 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);                }/* Sets the number of quantization bits when 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 channels when sampling */arg = CHANNELS;                Status = IOCTL (FD, SNDCTL_DSP_STEREO,&AMP;ARG);                if (status = =-1) perror ("Sndctl_dsp_stereo ioctl failed");                if (arg! = CHANNELS) perror ("Unable toset number of CHANNELS");                /* Set sampling frequency at sampling */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;}

the point of attention in the program is Open () parameter settings for the function, preceded by parameters O_rdwr , the result is always the error when the sound, the specific cause of error may be related to the driver settings. In this design, the correct setting is when recording , select o_rdonly, when playing , select o_wronly .



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.