mirror of
http://mpg123.de/trunk/.git
synced 2025-07-30 02:01:12 +03:00
doc/examples: fix some warnings, add mpg123_to_wav_reader64.c
git-svn-id: svn://scm.orgis.org/mpg123/trunk@5331 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
@ -23,6 +23,7 @@ EXTRA_DIST += \
|
||||
doc/windows-notes.html \
|
||||
doc/examples/mpg123_to_out123.c \
|
||||
doc/examples/mpg123_to_wav_replaced_io.c \
|
||||
doc/examples/mpg123_to_wav_reader64.c \
|
||||
doc/examples/scan.c \
|
||||
doc/examples/mpglib.c \
|
||||
doc/examples/id3dump.c \
|
||||
|
@ -2,6 +2,7 @@ targets = \
|
||||
feedseek \
|
||||
mpg123_to_out123 \
|
||||
mpg123_to_wav_replaced_io \
|
||||
mpg123_to_wav_reader64 \
|
||||
scan \
|
||||
id3dump \
|
||||
mpglib \
|
||||
@ -40,6 +41,9 @@ mpg123_to_out123: mpg123_to_out123.c
|
||||
mpg123_to_wav_replaced_io: mpg123_to_wav_replaced_io.c
|
||||
$(compile) -o $@ $< $(OUT123_CFLAGS) $(OUT123_LDFLAGS) $(linkflags)
|
||||
|
||||
mpg123_to_wav_reader64: mpg123_to_wav_reader64.c
|
||||
$(compile) -o $@ $< $(OUT123_CFLAGS) $(OUT123_LDFLAGS) $(linkflags)
|
||||
|
||||
feedseek: feedseek.c
|
||||
$(compile) -o feedseek feedseek.c $(OUT123_CFLAGS) $(OUT123_LDFLAGS) $(linkflags)
|
||||
|
||||
|
@ -69,7 +69,8 @@ int do_work(mpg123_handle *m)
|
||||
ret = mpg123_open_fd(m, STDIN_FILENO);
|
||||
if(ret != MPG123_OK) return ret;
|
||||
|
||||
while( (ret = mpg123_framebyframe_next(m)) == MPG123_OK || ret == MPG123_NEW_FORMAT )
|
||||
ssize_t wret = 0;
|
||||
while( !wret && (ret = mpg123_framebyframe_next(m)) == MPG123_OK || ret == MPG123_NEW_FORMAT )
|
||||
{
|
||||
unsigned long header;
|
||||
unsigned char *bodydata;
|
||||
@ -82,14 +83,20 @@ int do_work(mpg123_handle *m)
|
||||
for(i=0; i<4; ++i) hbuf[i] = (unsigned char) ((header >> ((3-i)*8)) & 0xff);
|
||||
|
||||
/* Now write out both header and data, fire and forget. */
|
||||
write(STDOUT_FILENO, hbuf, 4);
|
||||
write(STDOUT_FILENO, bodydata, bodybytes);
|
||||
wret = write(STDOUT_FILENO, hbuf, 4);
|
||||
if(!wret)
|
||||
wret = write(STDOUT_FILENO, bodydata, bodybytes);
|
||||
fprintf(stderr, "%zu: header 0x%08lx, %zu body bytes\n", ++count, header, bodybytes);
|
||||
}
|
||||
}
|
||||
|
||||
if(ret != MPG123_DONE)
|
||||
fprintf(stderr, "Some error occured (non-fatal?): %s\n", mpg123_strerror(m));
|
||||
fprintf(stderr, "Some error occured (non-fatal?): %s\n", mpg123_strerror(m));
|
||||
if(wret)
|
||||
{
|
||||
fprintf(stderr, "Write error.\n");
|
||||
ret = MPG123_ERR;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Done with %zu MPEG frames.\n", count);
|
||||
|
||||
|
203
doc/examples/mpg123_to_wav_reader64.c
Normal file
203
doc/examples/mpg123_to_wav_reader64.c
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
mpg123_to_wav_replaced_io.c
|
||||
|
||||
This is example code only sensible to be considered in the public domain.
|
||||
Initially written by Nicholas Humfrey (moved to 64 bit handle I/O by Thomas Orgis).
|
||||
|
||||
This example program demonstrates how to use libmpg123 to decode a file to WAV (writing via libsndfile), while doing the I/O (read and seek) with custom callback functions.
|
||||
This should cater for any situation where you have some special means to get to the data (like, mmapped files / plain buffers in memory, funky network streams).
|
||||
|
||||
Disregarding format negotiations, the basic synopsis is:
|
||||
|
||||
mpg123_init()
|
||||
mpg123_new()
|
||||
mpg123_replace_reader_handle()
|
||||
|
||||
mpg123_open_handle()
|
||||
mpg123_read()
|
||||
mpg123_close()
|
||||
|
||||
mpg123_delete()
|
||||
mpg123_exit()
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <mpg123.h>
|
||||
#include <out123.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#if MPG123_API_VERSION < 48
|
||||
#error "Need minimum mpg123 API version 48."
|
||||
#endif
|
||||
|
||||
|
||||
void usage(const char *cmd)
|
||||
{
|
||||
printf("Usage: %s <input> <output>\n", cmd);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
void cleanup(mpg123_handle *mh, out123_handle *ao)
|
||||
{
|
||||
out123_del(ao);
|
||||
/* It's really to late for error checks here;-) */
|
||||
mpg123_close(mh);
|
||||
mpg123_delete(mh);
|
||||
mpg123_exit();
|
||||
}
|
||||
|
||||
/* Simple handle for you private I/O data. */
|
||||
struct ioh { int fd; };
|
||||
|
||||
/* The callback functions; simple wrappers over standard I/O.
|
||||
They could be anything you like... */
|
||||
|
||||
static int read_cb(void *handle, void *buf, size_t sz, size_t *got)
|
||||
{
|
||||
if(!handle)
|
||||
return -1;
|
||||
struct ioh *h = handle;
|
||||
errno = 0;
|
||||
// Ideally, you check for singnals in here where they should not interrupt
|
||||
// operations (handle EINTR, for example).
|
||||
ssize_t gots = read(h->fd, buf, sz);
|
||||
if(gots < 0)
|
||||
{
|
||||
fprintf(stderr, "read error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(got)
|
||||
*got = (size_t)gots;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// You should be more careful if off_t < int64_t. Ideally, you know
|
||||
// you have 64 bit I/O.
|
||||
static int64_t lseek_cb(void *handle, int64_t offset, int whence)
|
||||
{
|
||||
if(!handle)
|
||||
return -1;
|
||||
int64_t ret;
|
||||
struct ioh *h = handle;
|
||||
ret = (int64_t)lseek(h->fd, (off_t)offset, whence);
|
||||
if(ret < 0) fprintf(stderr, "seek error: %s\n", strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The cleanup handler is called on mpg123_close(), it can cleanup your part of the mess... */
|
||||
void cleanup_cb(void *handle)
|
||||
{
|
||||
if(!handle)
|
||||
return;
|
||||
struct ioh *h = handle;
|
||||
close(h->fd);
|
||||
h->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mpg123_handle *mh = NULL;
|
||||
out123_handle *ao = NULL;
|
||||
unsigned char* buffer = NULL;
|
||||
size_t buffer_size = 0;
|
||||
size_t done = 0;
|
||||
int channels = 0, encoding = 0;
|
||||
long rate = 0;
|
||||
int err = MPG123_OK;
|
||||
off_t samples = 0;
|
||||
struct ioh *iohandle;
|
||||
|
||||
if (argc!=3) usage(argv[0]);
|
||||
printf( "Input file: %s\n", argv[1]);
|
||||
printf( "Output file: %s\n", argv[2]);
|
||||
|
||||
#if MPG123_API_VERSION < 46
|
||||
// Newer versions of the library don't need that anymore, but it is safe
|
||||
// to have the no-op call present for compatibility with old versions.
|
||||
err = mpg123_init();
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
iohandle = malloc(sizeof(struct ioh));
|
||||
iohandle->fd = open(argv[1], O_RDONLY);
|
||||
if(iohandle->fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Cannot open input file (%s).\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL
|
||||
/* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */
|
||||
|| mpg123_reader64(mh, read_cb, lseek_cb, cleanup_cb) != MPG123_OK
|
||||
|| mpg123_open_handle(mh, iohandle) != MPG123_OK
|
||||
/* Peek into track and get first output format. */
|
||||
|| mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK )
|
||||
{
|
||||
fprintf( stderr, "Trouble with mpg123: %s\n",
|
||||
mh==NULL ? mpg123_plain_strerror(err) : mpg123_strerror(mh) );
|
||||
cleanup(mh, ao);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(encoding != MPG123_ENC_SIGNED_16)
|
||||
{ /* Signed 16 is the default output format anyways; it would actually by only different if we forced it.
|
||||
So this check is here just for this explanation. */
|
||||
cleanup(mh, ao);
|
||||
fprintf(stderr, "Bad encoding: 0x%x!\n", encoding);
|
||||
return -2;
|
||||
}
|
||||
/* Ensure that this output format will not change (it could, when we allow it). */
|
||||
mpg123_format_none(mh);
|
||||
mpg123_format(mh, rate, channels, encoding);
|
||||
|
||||
printf("Creating 16bit WAV with %i channels and %liHz.\n", channels, rate);
|
||||
if(
|
||||
!(ao = out123_new())
|
||||
|| out123_open(ao, "wav", argv[2])
|
||||
|| out123_start(ao, rate, channels, encoding)
|
||||
)
|
||||
{
|
||||
fprintf(stderr, "Cannot create / start output: %s\n"
|
||||
, out123_strerror(ao));
|
||||
cleanup(mh, ao);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Buffer could be almost any size here, mpg123_outblock() is just some recommendation.
|
||||
Important, especially for sndfile writing, is that the size is a multiple of sample size. */
|
||||
buffer_size = mpg123_outblock( mh );
|
||||
buffer = malloc( buffer_size );
|
||||
|
||||
do
|
||||
{
|
||||
err = mpg123_read( mh, buffer, buffer_size, &done );
|
||||
out123_play(ao, buffer, done);
|
||||
samples += done/sizeof(short);
|
||||
/* We are not in feeder mode, so MPG123_OK, MPG123_ERR and MPG123_NEW_FORMAT are the only possibilities.
|
||||
We do not handle a new format, MPG123_DONE is the end... so abort on anything not MPG123_OK. */
|
||||
} while (done && err==MPG123_OK);
|
||||
|
||||
free(buffer);
|
||||
|
||||
if(err != MPG123_DONE)
|
||||
fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n",
|
||||
err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) );
|
||||
|
||||
samples /= channels;
|
||||
printf("%li samples written.\n", (long)samples);
|
||||
cleanup(mh, ao);
|
||||
free(iohandle);
|
||||
return 0;
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
This is example code only sensible to be considered in the public domain.
|
||||
Initially written by Nicholas Humfrey (moved to handle I/O by Thomas Orgis).
|
||||
|
||||
This example program demonstrates how to use libmpg123 to decode a file to WAV (writing via libsndfile), while doing the I/O (read and seek) with custom callback functions.
|
||||
This example program demonstrates how to use libmpg123 to decode a file to WAV (writing via libout123), while doing the I/O (read and seek) with custom callback functions.
|
||||
This should cater for any situation where you have some special means to get to the data (like, mmapped files / plain buffers in memory, funky network streams).
|
||||
|
||||
Disregarding format negotiations, the basic synopsis is:
|
||||
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <mpg123.h>
|
||||
#include <out123.h>
|
||||
|
Reference in New Issue
Block a user