API documentation for libmpg123, libout123, and libsyn123

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, NEWS.libout123, NEWS.libsyn123, and the overall NEWS file on libmpg123 versions and important changes between them.
Let me emphasize that the policy for the lib*123 family is to always stay backwards compatible -- only additions are planned (and it's not yet planned to change the plans;-).
mpg123_to_out123.c
Go to the documentation of this file.
1 /*
2  mpg123_to_wav.c
3 
4  This is example code only sensible to be considered in the public domain.
5  Initially written by Nicholas Humfrey.
6 
7  The most complicated part is about the choices to make about output format,
8  and prepare for the unlikely case a bastard mp3 might file change it.
9 */
10 
11 #include <out123.h>
12 #include <mpg123.h>
13 #include <stdio.h>
14 #include <strings.h>
15 
17 void usage(const char *cmd)
18 {
19  printf("Usage: %s <input> [<driver> [<output> [encoding [buffersize]]]]\n"
20  , cmd);
21  printf( "\nPlay MPEG audio from intput file to output file/device using\n"
22  "specified out123 driver, sample encoding and buffer size optional.\n\n" );
23  exit(99);
24 }
25 
28 {
29  out123_del(ao);
30  /* It's really to late for error checks here;-) */
31  mpg123_close(mh);
32  mpg123_delete(mh);
33 }
34 
36 int main(int argc, char *argv[])
37 {
38  mpg123_handle *mh = NULL;
39  out123_handle *ao = NULL;
40  char *infile = NULL;
41  char *driver = NULL;
42  char *outfile = NULL;
43  unsigned char* buffer = NULL;
44  const char *encname;
45  size_t buffer_size = 0;
46  size_t done = 0;
47  int channels = 0;
48  int encoding = 0;
49  int framesize = 1;
50  long rate = 0;
51  int err = MPG123_OK;
52  off_t samples = 0;
53 
54  if(argc<2)
55  usage(argv[0]);
56 
57  infile = argv[1];
58  if(argc >= 3)
59  driver = argv[2];
60  if(argc >= 4)
61  outfile = argv[3];
62  printf("Input file: %s\n", infile);
63  printf("Output driver: %s\n", driver ? driver : "<nil> (default)");
64  printf("Output file: %s\n", outfile ? outfile : "<nil> (default)");
65 
66 #if MPG123_API_VERSION < 46
67  // Newer versions of the library don't need that anymore, but it is safe
68  // to have the no-op call present for compatibility with old versions.
69  err = mpg123_init();
70 #endif
71  if(err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL)
72  {
73  fprintf(stderr, "Basic setup goes wrong: %s", mpg123_plain_strerror(err));
74  cleanup(mh, ao);
75  return -1;
76  }
77 
78  ao = out123_new();
79  if(!ao)
80  {
81  fprintf(stderr, "Cannot create output handle.\n");
82  cleanup(mh, ao);
83  return -1;
84  }
85 
86  if(argc >= 5)
87  { /* Make mpg123 support the desired encoding only for all rates. */
88  const long *rates;
89  size_t rate_count;
90  size_t i;
91  int enc;
92  /* If that is zero, you'll get the error soon enough from mpg123. */
93  enc = out123_enc_byname(argv[4]);
95  mpg123_rates(&rates, &rate_count);
96  for(i=0; i<rate_count; ++i)
97  mpg123_format(mh, rates[i], MPG123_MONO|MPG123_STEREO, enc);
98  }
99 
100  /* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */
101  if( mpg123_open(mh, infile) != MPG123_OK
102  /* Peek into track and get first output format. */
103  || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK )
104  {
105  fprintf( stderr, "Trouble with mpg123: %s\n", mpg123_strerror(mh) );
106  cleanup(mh, ao);
107  return -1;
108  }
109  if(out123_open(ao, driver, outfile) != OUT123_OK)
110  {
111  fprintf(stderr, "Trouble with out123: %s\n", out123_strerror(ao));
112  cleanup(mh, ao);
113  return -1;
114  }
115  /* It makes no sense for that to give an error now. */
116  out123_driver_info(ao, &driver, &outfile);
117  printf("Effective output driver: %s\n", driver ? driver : "<nil> (default)");
118  printf("Effective output file: %s\n", outfile ? outfile : "<nil> (default)");
119 
120  /* Ensure that this output format will not change
121  (it might, when we allow it). */
122  mpg123_format_none(mh);
123  mpg123_format(mh, rate, channels, encoding);
124 
125  encname = out123_enc_name(encoding);
126  printf( "Playing with %i channels and %li Hz, encoding %s.\n"
127  , channels, rate, encname ? encname : "???" );
128  if( out123_start(ao, rate, channels, encoding)
129  || out123_getformat(ao, NULL, NULL, NULL, &framesize) )
130  {
131  fprintf(stderr, "Cannot start output / get framesize: %s\n"
132  , out123_strerror(ao));
133  cleanup(mh, ao);
134  return -1;
135  }
136 
137  /* Buffer could be almost any size here, mpg123_outblock() is just some
138  recommendation. The size should be a multiple of the PCM frame size. */
139  buffer_size = argc >= 6 ? atol(argv[5]) : mpg123_outblock(mh);
140  buffer = malloc( buffer_size );
141 
142  do
143  {
144  size_t played;
145  err = mpg123_read( mh, buffer, buffer_size, &done );
146  played = out123_play(ao, buffer, done);
147  if(played != done)
148  {
149  fprintf(stderr
150  , "Warning: written less than gotten from libmpg123: %li != %li\n"
151  , (long)played, (long)done);
152  }
153  samples += played/framesize;
154  /* We are not in feeder mode, so MPG123_OK, MPG123_ERR and
155  MPG123_NEW_FORMAT are the only possibilities.
156  We do not handle a new format, MPG123_DONE is the end... so
157  abort on anything not MPG123_OK. */
158  } while (done && err==MPG123_OK);
159 
160  free(buffer);
161 
162  if(err != MPG123_DONE)
163  fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n",
164  err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) );
165 
166  printf("%li samples written.\n", (long)samples);
167  cleanup(mh, ao);
168  return 0;
169 }
struct mpg123_handle_struct mpg123_handle
Definition: mpg123.h:175
MPG123_EXPORT size_t out123_play(out123_handle *ao, void *buffer, size_t bytes)
struct out123_struct out123_handle
Definition: out123.h:119
MPG123_EXPORT int out123_enc_byname(const char *name)
MPG123_EXPORT void mpg123_rates(const long **list, size_t *number)
MPG123_EXPORT int out123_open(out123_handle *ao, const char *driver, const char *device)
MPG123_EXPORT size_t mpg123_outblock(mpg123_handle *mh)
int main(int argc, char *argv[])
MPG123_EXPORT int out123_driver_info(out123_handle *ao, char **driver, char **device)
MPG123_EXPORT const char * mpg123_strerror(mpg123_handle *mh)
MPG123_EXPORT int mpg123_close(mpg123_handle *mh)
MPG123_EXPORT void out123_del(out123_handle *ao)
MPG123_EXPORT const char * mpg123_plain_strerror(int errcode)
MPG123_EXPORT int mpg123_init(void)
MPG123_EXPORT const char * out123_strerror(out123_handle *ao)
MPG123_EXPORT int mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
MPG123_EXPORT int out123_getformat(out123_handle *ao, long *rate, int *channels, int *encoding, int *framesize)
void usage(const char *cmd)
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh)
MPG123_EXPORT int out123_start(out123_handle *ao, long rate, int channels, int encoding)
MPG123_EXPORT int mpg123_read(mpg123_handle *mh, void *outmemory, size_t outmemsize, size_t *done)
MPG123_EXPORT int mpg123_format_none(mpg123_handle *mh)
void cleanup(mpg123_handle *mh, out123_handle *ao)
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
MPG123_EXPORT out123_handle * out123_new(void)
MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path)
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
MPG123_EXPORT const char * out123_enc_name(int encoding)
Hopefully valid HTML! Valid CSS!