You could access this page securely.

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;-).
Loading...
Searching...
No Matches
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
17void 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
36int 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). */
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",
165
166 printf("%li samples written.\n", (long)samples);
167 cleanup(mh, ao);
168 return 0;
169}
MPG123_EXPORT const char * mpg123_plain_strerror(int errcode)
MPG123_EXPORT const char * mpg123_strerror(mpg123_handle *mh)
@ MPG123_ERR
Definition mpg123.h:532
@ MPG123_DONE
Definition mpg123.h:529
@ MPG123_OK
Definition mpg123.h:533
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh)
struct mpg123_handle_struct mpg123_handle
Definition mpg123.h:222
MPG123_EXPORT int mpg123_init(void)
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
MPG123_EXPORT int mpg123_close(mpg123_handle *mh)
MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path)
MPG123_EXPORT int mpg123_read(mpg123_handle *mh, void *outmemory, size_t outmemsize, size_t *done)
MPG123_EXPORT size_t mpg123_outblock(mpg123_handle *mh)
MPG123_EXPORT int mpg123_format_none(mpg123_handle *mh)
MPG123_EXPORT void mpg123_rates(const long **list, size_t *number)
MPG123_EXPORT int mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
@ MPG123_STEREO
Definition mpg123.h:673
@ MPG123_MONO
Definition mpg123.h:672
MPG123_EXPORT const char * out123_enc_name(int encoding)
MPG123_EXPORT int out123_open(out123_handle *ao, const char *driver, const char *device)
MPG123_EXPORT int out123_enc_byname(const char *name)
MPG123_EXPORT int out123_driver_info(out123_handle *ao, char **driver, char **device)
struct out123_struct out123_handle
Definition out123.h:119
MPG123_EXPORT out123_handle * out123_new(void)
MPG123_EXPORT void out123_del(out123_handle *ao)
MPG123_EXPORT int out123_start(out123_handle *ao, long rate, int channels, int encoding)
MPG123_EXPORT int out123_getformat(out123_handle *ao, long *rate, int *channels, int *encoding, int *framesize)
MPG123_EXPORT const char * out123_strerror(out123_handle *ao)
MPG123_EXPORT size_t out123_play(out123_handle *ao, void *buffer, size_t bytes)
@ OUT123_OK
Definition out123.h:230
int main(int argc, char *argv[])
void cleanup(mpg123_handle *mh, out123_handle *ao)
void usage(const char *cmd)
Hopefully valid HTML! Valid CSS!