# 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;-).
feedseek.c
Go to the documentation of this file.
1 /*
2 feedseek: test program for libmpg123, showing how to use fuzzy seeking in feeder mode
3
4 This is example code only sensible to be considered in the public domain.
5
6 It takes MPEG data from standard input and feeds that to libmpg123, combined
7 with a fuzzy seek. Libmpg123 could access stdin in other ways directly, but
8 usage of the feeder API is the point here.
9 */
10
11 #define _POSIX_C_SOURCE 200112L
12 #include <mpg123.h>
13 #include <out123.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16
17 #define INBUFF 16384 * 2 * 2
23 #define CHECK(cond, ...) if(!(cond)){ fprintf(stderr, __VA_ARGS__); goto bad_end; }
24
26 int main(int argc, char **argv)
27 {
28 unsigned char buf[INBUFF];
29 mpg123_handle *m = NULL;
30 out123_handle *o = NULL;
31 const char *driver = NULL;
32 char *device = NULL;
33 int ret = 0;
34 off_t inoffset;
35 off_t cur_inoffset;
36 off_t seek_point = 0;
37 off_t seek_target;
38
39 // 0. Argument parsing.
40
41 if(argc < 2)
42 {
43 fprintf(stderr, "Usage:\n\n %s <offset> [outfile] < <MPEG input data>\n", argv[0]);
44 fprintf( stderr, "\n"
45 "This will decode standard input to the default audio device or the\n"
46 "given output file as decoded WAV after seeking to the given PCM sample\n"
47 "offset to demonstrate fuzzy seeking\n" );
48 return 1;
49 }
50
51 seek_point = atol(argv[1]);
52 CHECK(seek_point >= 0, "No negative offset, please.\n")
53
54 if(argc >= 3)
55 {
56 driver = "wav";
57 device = argv[2];
58 }
59
60 // 1. Initialize libmpg123 and libout123 handles.
61
62 #if MPG123_API_VERSION < 46
63 // Newer versions of the library don't need that anymore, but it is safe
64 // to have the no-op call present for compatibility with old versions.
65 mpg123_init();
66 #endif
67
68 m = mpg123_new(NULL, &ret);
69 CHECK(m != NULL, "Unable to create mpg123 handle: %s\n", mpg123_plain_strerror(ret))
70
71 o = out123_new();
72 CHECK(o != NULL, "Unable to create out123 handle.\n")
73
74 ret = out123_open(o, driver, device);
75 CHECK(ret == OUT123_OK, "Failed to open output device: %s\n", out123_strerror(o))
76
77 mpg123_param(m, MPG123_VERBOSE, 2, 0);
78
79 mpg123_param(m, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0);
80 CHECK(ret == MPG123_OK, "Unable to set library options: %s\n", mpg123_plain_strerror(ret))
81
82 // 2. Open the feeder, feed data until libmpg123 can tell us where to go in the input
83 // for the desired output offset.
84
85 ret = mpg123_open_feed(m);
86 CHECK(ret == MPG123_OK, "Unable open feed: %s\n", mpg123_plain_strerror(ret))
87
88 fprintf(stderr, "\nDetermining input offset for seek ...\n");
89 /* That condition is tricky... parentheses are crucial... */
90 while( (seek_target = mpg123_feedseek(m, seek_point, SEEK_SET, &inoffset))
91 == MPG123_NEED_MORE )
92 {
93 fprintf(stderr, " *** need more data before deciding on fuzzy input offset ***\n");
94 size_t len = fread(buf, 1, INBUFF, stdin);
95 if(len < 0 || (len == 0 && (feof(stdin) || ferror(stdin))))
96 break;
97 ret = mpg123_feed(m, buf, len);
98 CHECK(ret == MPG123_OK, "Error feeding the decoder: %s", mpg123_strerror(m))
99 }
100 CHECK(ret == MPG123_OK, "Feedseek failed: %s\n", mpg123_strerror(m))
101 fprintf( stderr, "Fuzzy seek to %lld, actually to %lld.\n"
102 , (long long)seek_point, (long long)seek_target );
103 CHECK(inoffset >=0 , "Bogus input offset: %lld\n", (long long)inoffset)
104
105 // 3. Go to the indicated input offset.
106
107 fprintf(stderr, "\nSeeking to input offset ...\n");
108 // In a normal file, we would call fseek() here, for stdin, we just consume data.
109 while( (cur_inoffset=ftello(stdin)) < inoffset && !ferror(stdin) )
110 {
111 CHECK(cur_inoffset >= 0, "Cannot tell input position.\n")
112 off_t block = inoffset - cur_inoffset;
113 if(block > INBUFF)
114 block = INBUFF;
115 if(fread(buf, 1, block, stdin) == 0 && feof(stdin))
116 break;
117 }
118 CHECK( ftello(stdin) == inoffset, "Input seeking failed: %lld != %lld\n"
119 , (long long)ftello(stdin), (long long)inoffset )
120
121 // 4. Feed the decoder from that point on and get the decoded audio.
122
123 fprintf(stderr, "\nStarting decode...\n");
124 while(1)
125 {
126 size_t len = fread(buf, sizeof(unsigned char), INBUFF, stdin);
127 if(len <= 0)
128 break;
129 ret = mpg123_feed(m, buf, len);
130
131 while(ret != MPG123_ERR && ret != MPG123_NEED_MORE)
132 {
133 off_t num;
134 unsigned char *audio;
135 size_t bytes;
136 ret = mpg123_decode_frame(m, &num, &audio, &bytes);
137 if(ret == MPG123_NEW_FORMAT)
138 {
139 long rate;
140 int channels, enc;
141 mpg123_getformat(m, &rate, &channels, &enc);
142 fprintf(stderr
143 , "New format: %li Hz, %i channels, encoding value %i\n"
144 , rate, channels, enc );
145 ret = out123_start(o, rate, channels, enc);
146 CHECK(ret == OUT123_OK, "Cannot (re)start audio output with given format.\n")
147 }
148 CHECK(out123_play(o, audio, bytes) == bytes, "Output error: %s", out123_strerror(o))
149 }
150
151 CHECK(ret != MPG123_ERR, "Error: %s", mpg123_strerror(m))
152 }
153
154 fprintf(stderr, "Finished\n");
155
156 good_end: // Everything went fine: go directly to the cleanup section.
157 goto end;
158 bad_end: // Some unspecified error, set error state and clean up.
159 ret = -1;
160 end: // Clean up and return.
161 out123_del(o);
162 mpg123_delete(m);
163 return ret ? EXIT_FAILURE : EXIT_SUCCESS;
164 }
MPG123_SEEKBUFFER
@ MPG123_SEEKBUFFER
Definition: mpg123.h:325
mpg123_plain_strerror
const MPG123_EXPORT char * mpg123_plain_strerror(int errcode)
mpg123_getformat
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
mpg123_delete
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh)
out123.h
OUT123_OK
@ OUT123_OK
Definition: out123.h:230
MPG123_ERR
@ MPG123_ERR
Definition: mpg123.h:532
MPG123_GAPLESS
@ MPG123_GAPLESS
Definition: mpg123.h:323
INBUFF
#define INBUFF
Definition: feedseek.c:17
main
int main(int argc, char **argv)
Definition: feedseek.c:26
out123_start
MPG123_EXPORT int out123_start(out123_handle *ao, long rate, int channels, int encoding)
mpg123_handle
struct mpg123_handle_struct mpg123_handle
Definition: mpg123.h:222
mpg123_strerror
const MPG123_EXPORT char * mpg123_strerror(mpg123_handle *mh)
MPG123_VERBOSE
@ MPG123_VERBOSE
Definition: mpg123.h:286
out123_handle
struct out123_struct out123_handle
Definition: out123.h:119
mpg123_feedseek
MPG123_EXPORT off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
out123_strerror
const MPG123_EXPORT char * out123_strerror(out123_handle *ao)
out123_new
MPG123_EXPORT out123_handle * out123_new(void)
mpg123_feed
MPG123_EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
mpg123_open_feed
MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh)
mpg123_new
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
CHECK
#define CHECK(cond,...)
Definition: feedseek.c:23
MPG123_FUZZY
@ MPG123_FUZZY
Definition: mpg123.h:326
out123_play
MPG123_EXPORT size_t out123_play(out123_handle *ao, void *buffer, size_t bytes)
out123_open
MPG123_EXPORT int out123_open(out123_handle *ao, const char *driver, const char *device)
MPG123_FLAGS
@ MPG123_FLAGS
Definition: mpg123.h:287
MPG123_NEW_FORMAT
@ MPG123_NEW_FORMAT
Definition: mpg123.h:530
out123_del
MPG123_EXPORT void out123_del(out123_handle *ao)
mpg123_init
MPG123_EXPORT int mpg123_init(void)
MPG123_OK
@ MPG123_OK
Definition: mpg123.h:533
mpg123_decode_frame
MPG123_EXPORT int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
mpg123_param
MPG123_EXPORT int mpg123_param(mpg123_handle *mh, enum mpg123_parms type, long value, double fvalue)
MPG123_NEED_MORE
@ MPG123_NEED_MORE
Definition: mpg123.h:531