由于使用SDL所以可以在多数平台下编译通过。
- #include <stdlib.h>
- #include <math.h>
- #include <SDL/SDL.h>
- #include <SDL/SDL_main.h>
- #include <assert.h>
- #include <unistd.h>
- #include <sys/select.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <time.h>
- #include "mpg123.h"
-
- static Uint8 buffer[8192];
- static int offset = 0;
- static int length = 0;
- static int tryexit();
- static Uint8 __outbuf[1638400];
-
- void example_mixaudio(void *unused, Uint8 * stream, int len)
- {
- int count = len;
- if (offset + count > length){
- count = length - offset;
- }
- memcpy(stream, __outbuf+offset, count);
- offset += count;
- }
-
- static void play_setup(long rate, int chanel)
- {
- SDL_AudioSpec *desired, *obtained;
- obtained = (SDL_AudioSpec *) malloc(sizeof(SDL_AudioSpec));
- desired = (SDL_AudioSpec *) malloc(sizeof(SDL_AudioSpec));
- desired->freq = rate;
- desired->format = AUDIO_S16;
- desired->samples = 4096;
- desired->callback = example_mixaudio;
- desired->userdata = NULL;
- desired->channels = chanel;
- if (SDL_OpenAudio(desired, obtained) < 0) {
- fprintf(stderr, "AudioMixer, Unable to open audio: %s\n",
- SDL_GetError());
- exit(-1);
- }
-
-
-
-
-
-
-
- SDL_PauseAudio(0);
- free(desired);
- free(obtained);
- }
-
- static int play_audio(Uint8 buf[], int len)
- {
- int cut = 0;
- int count = 0;
- timeval tv;
- do{
- SDL_LockAudio();
- length -= offset;
- memmove(__outbuf, __outbuf+offset, length);
- offset = 0;
- count = sizeof(__outbuf)-length;
- if (cut + count > len){
- count = len - cut;
- }
- memcpy(__outbuf+length, buf+cut, count);
- length += count;
- cut += count;
- SDL_UnlockAudio();
- if (cut < len && tryexit()==true){
- tv.tv_usec = 20000;
- tv.tv_sec = 0;
- select(0, NULL, NULL, NULL, &tv);
- }
- }while(cut < len && tryexit()==true);
- return 0;
- }
-
- static int tryexit()
- {
-
- static bool running = true;
- SDL_Event event;
- if(running) {
- if(SDL_PollEvent(&event)) {
- switch (event.type) {
- case SDL_KEYDOWN:
- switch (event.key.keysym.sym) {
- case SDLK_ESCAPE:
- running = false;
- break;
- default:
- break;
- }
- break;
- case SDL_QUIT:
- running = false;
- break;
- }
- SDL_Delay(1);
- }
- SDL_Delay(1);
- }
-
- if (running == false){
- SDL_Quit();
- }
- return running;
- }
-
- static void load_file(mpg123_handle *mh, const char *path)
- {
- int err;
- unsigned int n;
- unsigned int done;
- Uint8 outbuf[1638400];
-
- FILE *fp = fopen(path, "rb");
- if (fp == NULL){
- return;
- }
- while(feof(fp) == 0 && tryexit()==true){
- n = fread(buffer, 1, sizeof(buffer), fp);
- err = mpg123_decode(mh, buffer, n, outbuf, 163840, &done);
- if (err == MPG123_NEW_FORMAT){
- long rate;
- int channels, enc;
- mpg123_getformat(mh, &rate, &channels, &enc);
- printf("new format\n");
- play_setup(rate, channels);
- }
- play_audio(outbuf, done);
- while(err!=MPG123_NEED_MORE && err!=MPG123_ERR && tryexit()==true){
- err = mpg123_decode(mh, NULL, 0, outbuf, 163840, &done);
- play_audio(outbuf, done);
- }
- if (err == MPG123_ERR){
- printf("err = %s\n", mpg123_strerror(mh));
- break;
- }
- }
- fclose(fp);
- }
-
- int main(int argc, char *argv[])
- {
- int i;
- int err = 0;
- printf("Initializing SDL.\n");
- if ((SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1)) {
- printf("Could not initialize SDL: %s.\n", SDL_GetError());
- exit(-1);
- }
- SDL_Surface *screen = SDL_SetVideoMode(200, 200, 16, SDL_SWSURFACE);
- SDL_WM_SetCaption("Audio Example", 0);
- printf("SDL initialized.\n");
- for (i=1; i<argc; i++){
- mpg123_init();
- mpg123_handle *mh = mpg123_new(NULL, &err);
- assert(mh != NULL);
- err = mpg123_open_feed(mh);
- assert(err == MPG123_OK);
- load_file(mh, argv[i]);
- mpg123_close(mh);
- mpg123_delete(mh);
- mpg123_exit();
- }
- while (tryexit() == true){
- ;
- }
- return 0;
- }
(pagxir) |