mpg123 logo
download : svn :: features :: sf.net project - bug tracker :: news archive
libmpg123 API :: hacking :: testing :: benchmarking :: FAQ :: links :: contact
Note: This API doc is automatically generated from the current development version that you can get via Subversion or as a daily snapshot from http://mpg123.org/snapshot. There may be differences (additions) compared to the latest stable release. See NEWS.libmpg123 and the overall NEWS file on libmpg123 versions and important changes between them.
Let me emphasize that the policy for libmpg123 is to always stay backwards compatible -- only additions are planned (and it's not yet planned to change the plans;-).

mpg123_to_wav.c

Go to the documentation of this file.
00001 /*
00002         mpg123_to_wav.c
00003 
00004         copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1
00005         see COPYING and AUTHORS files in distribution or http://mpg123.org
00006         initially written by Nicholas Humfrey
00007 */
00008 
00009 #include <stdio.h>
00010 #include <strings.h>
00011 #include <mpg123.h>
00012 #include <sndfile.h>
00013 
00014 
00015 void usage()
00016 {
00017         printf("Usage: mpg123_to_wav <input> <output> [s16|f32 [ <buffersize>]]\n");
00018         exit(99);
00019 }
00020 
00021 void cleanup(mpg123_handle *mh)
00022 {
00023         /* It's really to late for error checks here;-) */
00024         mpg123_close(mh);
00025         mpg123_delete(mh);
00026         mpg123_exit();
00027 }
00028 
00029 int main(int argc, char *argv[])
00030 {
00031         SNDFILE* sndfile = NULL;
00032         SF_INFO sfinfo;
00033         mpg123_handle *mh = NULL;
00034         unsigned char* buffer = NULL;
00035         size_t buffer_size = 0;
00036         size_t done = 0;
00037         int  channels = 0, encoding = 0;
00038         long rate = 0;
00039         int  err  = MPG123_OK;
00040         off_t samples = 0;
00041 
00042         if (argc<3) usage();
00043         printf( "Input file: %s\n", argv[1]);
00044         printf( "Output file: %s\n", argv[2]);
00045         
00046         err = mpg123_init();
00047         if(err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL)
00048         {
00049                 fprintf(stderr, "Basic setup goes wrong: %s", mpg123_plain_strerror(err));
00050                 cleanup(mh);
00051                 return -1;
00052         }
00053 
00054         /* Simple hack to enable floating point output. */
00055         if(argc >= 4 && !strcmp(argv[3], "f32")) mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.);
00056 
00057             /* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */
00058         if(    mpg123_open(mh, argv[1]) != MPG123_OK
00059             /* Peek into track and get first output format. */
00060             || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK )
00061         {
00062                 fprintf( stderr, "Trouble with mpg123: %s\n", mpg123_strerror(mh) );
00063                 cleanup(mh);
00064                 return -1;
00065         }
00066 
00067         if(encoding != MPG123_ENC_SIGNED_16 && encoding != MPG123_ENC_FLOAT_32)
00068         { /* Signed 16 is the default output format anyways; it would actually by only different if we forced it.
00069              So this check is here just for this explanation. */
00070                 cleanup(mh);
00071                 fprintf(stderr, "Bad encoding: 0x%x!\n", encoding);
00072                 return -2;
00073         }
00074         /* Ensure that this output format will not change (it could, when we allow it). */
00075         mpg123_format_none(mh);
00076         mpg123_format(mh, rate, channels, encoding);
00077 
00078         bzero(&sfinfo, sizeof(sfinfo) );
00079         sfinfo.samplerate = rate;
00080         sfinfo.channels = channels;
00081         sfinfo.format = SF_FORMAT_WAV|(encoding == MPG123_ENC_SIGNED_16 ? SF_FORMAT_PCM_16 : SF_FORMAT_FLOAT);
00082         printf("Creating WAV with %i channels and %liHz.\n", channels, rate);
00083 
00084         sndfile = sf_open(argv[2], SFM_WRITE, &sfinfo);
00085         if(sndfile == NULL){ fprintf(stderr, "Cannot open output file!\n"); cleanup(mh); return -2; }
00086 
00087         /* Buffer could be almost any size here, mpg123_outblock() is just some recommendation.
00088            Important, especially for sndfile writing, is that the size is a multiple of sample size. */
00089         buffer_size = argc >= 5 ? atol(argv[4]) : mpg123_outblock(mh);
00090         buffer = malloc( buffer_size );
00091 
00092         do
00093         {
00094                 sf_count_t more_samples;
00095                 err = mpg123_read( mh, buffer, buffer_size, &done );
00096                 more_samples = encoding == MPG123_ENC_SIGNED_16
00097                         ? sf_write_short(sndfile, (short*)buffer, done/sizeof(short))
00098                         : sf_write_float(sndfile, (float*)buffer, done/sizeof(float));
00099                 if(more_samples < 0 || more_samples*mpg123_encsize(encoding) != done)
00100                 {
00101                         fprintf(stderr, "Warning: Written number of samples does not match the byte count we got from libmpg123: %li != %li\n", (long)(more_samples*mpg123_encsize(encoding)), (long)done);
00102                 }
00103                 samples += more_samples;
00104                 /* We are not in feeder mode, so MPG123_OK, MPG123_ERR and MPG123_NEW_FORMAT are the only possibilities.
00105                    We do not handle a new format, MPG123_DONE is the end... so abort on anything not MPG123_OK. */
00106         } while (err==MPG123_OK);
00107 
00108         if(err != MPG123_DONE)
00109         fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n",
00110                  err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) );
00111 
00112         sf_close( sndfile );
00113 
00114         samples /= channels;
00115         printf("%li samples written.\n", (long)samples);
00116         cleanup(mh);
00117         return 0;
00118 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines