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
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
26int 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.
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
78
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))
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
156good_end: // Everything went fine: go directly to the cleanup section.
157 goto end;
158bad_end: // Some unspecified error, set error state and clean up.
159 ret = -1;
160end: // Clean up and return.
161 out123_del(o);
162 mpg123_delete(m);
163 return ret ? EXIT_FAILURE : EXIT_SUCCESS;
164}
#define INBUFF
Definition feedseek.c:17
#define CHECK(cond,...)
Definition feedseek.c:23
int main(int argc, char **argv)
Definition feedseek.c:26
MPG123_EXPORT const char * mpg123_plain_strerror(int errcode)
MPG123_EXPORT const char * mpg123_strerror(mpg123_handle *mh)
@ MPG123_NEED_MORE
Definition mpg123.h:531
@ MPG123_ERR
Definition mpg123.h:532
@ MPG123_NEW_FORMAT
Definition mpg123.h:530
@ 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_param(mpg123_handle *mh, enum mpg123_parms type, long value, double fvalue)
MPG123_EXPORT int mpg123_init(void)
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
@ MPG123_FUZZY
Definition mpg123.h:326
@ MPG123_SEEKBUFFER
Definition mpg123.h:325
@ MPG123_GAPLESS
Definition mpg123.h:323
@ MPG123_VERBOSE
Definition mpg123.h:286
@ MPG123_FLAGS
Definition mpg123.h:287
MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh)
MPG123_EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
MPG123_EXPORT int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
MPG123_EXPORT off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
MPG123_EXPORT int out123_open(out123_handle *ao, const char *driver, const 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 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
Hopefully valid HTML! Valid CSS!