Libmad decodes mp3 to generate PCM files

Source: Internet
Author: User

In a previous article, I introduced how to use libmad in Linux to decode and play MP3 files, compile the source code, and play MP3 files normally, however, in the project, MP3 files need to be decoded into PCM files. Therefore, you need to modify the previous code based on the original code, so that you can test it.

/** This program is improved from minimad. For more details, see minimad. c ** myminimad. c, 2009/12/25, Sichuan University, China ** Compilation: GCC myminimad. c-o myminimad-LMAD-lasound * Run :. /myminimad filename.mp3 ** modification: * use libmad to decode MP3 and save it as a PCM file. * Compilation: GCC myminimad. c-o myminimad-LMAD * Run :. /myminimad filename=outputfilename. PCM **/# include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <sys/STAT. h> # include <sys/Mman. h> // # include <sys/Soundcard. h> # include <sys/IOCTL. h> # include <sys/fcntl. h> # include <sys/types. h> # include <mad. h> // # include <ALSA/asoundlib. h> # define sample_rate 44100 # define channels 2 # define pcm_device "plughw: 0, 0 "static snd_pcm_hw_params_t * hwparams = NULL; static snd_pcm_t * pcm_handle = NULL; struct buffer {unsigned char const * start; unsigned long length ;}; static int decode (unsigned char const *, unsigned long); // static int init_alsa (); file * OUTFILE; int main (INT argc, char * argv []) {struct Stat; void * OFDM; char const * file; int FD; If (argc! = 3) Return-1; OUTFILE = fopen (argv [2], "W +"); file = argv [1]; FD = open (file, o_rdonly ); if (fstat (FD, & Stat) =-1 | stat. st_size = 0) Return-1; OFDM = MMAP (0, stat. st_size, prot_read, map_shared, FD, 0); // copy the file content to the memory if (OFDM = map_failed) Return-1; // If (init_alsa () =-1) // {// fprintf (stderr, "init_alsa () Error/N"); // return-1; //} decode (OFDM, stat. st_size); // decode fclose (OUTFILE );/ /Close the file pointer if (munmap (OFDM, stat. st_size) =-1) Return-1; return 0;} // static int init_alsa () // {// snd_pcm_stream_t stream = snd_pcm_stream_playback; // char * pcm_name; // int rate = sample_rate;/* sample rate * // int exact_rate;/* Sample Rate returned by * // pcm_name = strdup (pcm_device ); // snd_pcm_hw_params_alloca (& hwparams); // If (snd_pcm_open (& pcm_handle, pcm_name, stream, 0) <0) // {// fp Rintf (stderr, "error opening PCM device % s/n", pcm_name); // return-1; //} // If (snd_pcm_hw_params_any (pcm_handle, hwparams) <0) // {// fprintf (stderr, "can not configure this PCM device. /n "); // return-1; //} // If (snd_pcm_hw_params_set_access (pcm_handle, hwparams, snd_pcm_access_rw_interleaved) <0) // {// fprintf (stderr, "Error setting access. /n "); // return-1; //} // If (snd_pcm_hw_params_s Et_format (pcm_handle, hwparams, snd_pcm_format_s16_le) <0) // {// fprintf (stderr, "error setting format. /n "); // return-1; //} // exact_rate = rate; // If (snd_pcm_hw_params_set_rate_near (pcm_handle, hwparams, & exact_rate, 0) <0) // {// fprintf (stderr, "error setting rate. /n "); // return-1; //} // If (rate! = Exact_rate) // {// fprintf (stderr, "the rate % d Hz is not supported by your hardware. /n => using % d Hz instead. /n ", rate, exact_rate); //} // If (snd_pcm_hw_params_set_channels (pcm_handle, hwparams, channels) <0) // {// fprintf (stderr, "Error setting channels. /n "); // return-1; //} // If (snd_pcm_hw_params (pcm_handle, hwparams) <0) // {// fprintf (stderr, "Error setting HW Params. /n "); // return -1; //} // return 0; //} static Enum mad_flow input (void * data, struct mad_stream * stream) {struct buffer * buffer = data; If (! Buffer-> length) return mad_flow_stop; mad_stream_buffer (stream, buffer-> Start, buffer-> length); buffer-> length = 0; return mad_flow_continue ;} /* This section is the PCM audio after processing the sample */static inline signed int Scale (mad_fixed_t sample) {sample + = (1l <(mad_f_fracbits-16 )); if (sample> = mad_f_one) Sample = mad_f_one-1; else if (sample <-mad_f_one) Sample =-mad_f_one; return sample> (mad_f_fracbits + 1-16 );} static Enum mad_flow output (void * data, struct mad_header const * Header, struct mad_pcm * PCM) {unsigned int nchannels, nsamples, N; mad_fixed_t const * left_ch, * right_ch; unsigned char output [6912], * outputptr; int FMT, wrote, speed, exact_rate, err, Dir; nchannels = PCM-> channels; n = nsamples = PCM-> length; left_ch = PCM-> samples [0]; right_ch = PCM-> samples [1]; // FMt = afmt_s16_le; // speed = PCM-> samplerate * 2; /* the playback speed is twice the sampling rate */outputptr = output; // point outputptr to output while (nsamples --) {signed int sample; sample = Scale (* left_ch ++); * (outputptr ++) = sample> 0; * (outputptr ++) = sample> 8; if (nchannels = 2) {sample = Scale (* right_ch ++); * (outputptr ++) = sample> 0; * (outputptr ++) = sample> 8 ;}}outputptr = output; // since the previous operation points the outputptr pointer to the end, you need to move the pointer to the front fwrite (outputptr, 1, N * 2 * nchannels, OUTFILE); // snd_pcm_writei (pcm_handle, outputptr, n); outputptr = output; // After the file is written, the outputptr pointer is moved to the end, in this case, you need to move the pointer to the frontend return mad_flow_continue;} static Enum mad_flow error (void * data, struct mad_stream * stream, struct mad_frame * frame) {return mad_flow_continue ;} static int decode (unsigned char const * Start, unsigned long length) {struct buffer; struct mad_decoder decoder; int result; buffer. start = start; buffer. length = length; mad_decoder_init (& decoder, & buffer, input, 0, 0, output, error, 0); mad_decoder_options (& decoder, 0); Result = mad_decoder_run (& decoder, mad_decoder_mode_sync); mad_decoder_finish (& decoder); return result ;}

Run GCC myminimad. C-o myminimad-LMAD on the terminal to generate a tool for decoding MP3 files and generating PCM.

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.