ssize_t load_audio_file(const char *name, char **data, size_t *size) { mm_file mf; unsigned channels, rate; const size_t def_size = 16 * 1024; size_t offset = 0; ssize_t read = 0; double start = get_time(); /* make compiler happy */ start *= 1.0; assert(name); assert(data); assert(size); if (mm_open_fp(&mf, sOpen(name, "rb", FT_AUDIO)) < 0) { return -1; } if (mm_audio_info(&mf, &channels, &rate) < 0) { CWARNING3(audio, "no audio data in file `%s'", name); mm_close(&mf); return -1; } if (channels != 1 || rate != 11025) { CERROR3(audio, "file `%s' should be mono, 11025Hz", name); mm_close(&mf); return -1; } if (!*data) { *data = (char *)xmalloc(*size = def_size); } while (0 < (read = mm_decode_audio(&mf, *data + offset, *size - offset))) { offset += read; if (*size <= offset) { *data = (char *)xrealloc(*data, *size *= 2); } } mm_close(&mf); CDEBUG4(audio, "loading file `%s' took %5.4f seconds", name, get_time() - start); return offset; }
void dbfile_close(pgctx_t *ctx) { int i; for(i=0; i<NR_DB_CONTEXT; i++) { if (dbctx[i] == ctx) { dbctx[i] = NULL; } } pmem_retire(&ctx->mm, _ptr(ctx, ctx->root->heap), 0); mm_close(&ctx->mm); }
int main(int argc, char **argv) { char *file = NULL; int have_video = 0, have_audio = 0; unsigned h = 0, w = 0; float fps = 0.0; unsigned ch = 0, hz = 0; struct audiobuf abuf; int end = 0; SDL_Surface *display = NULL; SDL_Overlay *ovl = NULL; SDL_Event event; mm_file media; if (argc > 1) file = argv[1]; else usage(argv[0]); if (mm_open(&media, file) <= 0) eprintf("No audio or video in `%s'\n", file); if (mm_video_info(&media, &w, &h, &fps) >= 0) { printf("Video data: %dx%d, %gfps\n", w, h, fps); have_video = 1; } if (mm_audio_info(&media, &ch, &hz) >= 0) { printf("Audio data: %s, %dHz\n", (ch == 1) ? "mono" : "stereo", hz); have_audio = 1; } if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0) eprintf("Sdl init failed: %s\n", SDL_GetError()); if (have_video) { if ((display = SDL_SetVideoMode(w, h, 24, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL) eprintf("SDL_SetVideoMode: %s\n", SDL_GetError()); if ((ovl = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, display)) == NULL) eprintf("SDL_CreateYUVOverlay: %s\n", SDL_GetError()); } if (have_audio) { int bytes; int bps; double tdiff; SDL_AudioSpec desired; desired.channels = ch; desired.freq = hz; desired.format = AUDIO_U8; bps = ch * 1; desired.samples = 4096; desired.callback = audio_cb; desired.userdata = &abuf; if (SDL_OpenAudio(&desired, NULL) < 0) eprintf("SDL_OpenAudio: %s\n", SDL_GetError()); abuf.size = 4 * 4096; abuf.off = 0; abuf.bytes = 0; abuf.buf = xmalloc(abuf.size); tdiff = get_time(); while ((bytes = mm_decode_audio(&media, abuf.buf + abuf.bytes, abuf.size - abuf.bytes)) > 0) { abuf.bytes += bytes; if (abuf.size - abuf.bytes <= 4096) abuf.buf = xrealloc(abuf.buf, abuf.size *= 2); }; if (bytes < 0) eperror("convert_audio"); printf("Decoding: %.3f seconds\n", get_time() - tdiff); printf("Audio: %d samples, %.2f seconds\n", abuf.bytes / bps, (double) (abuf.bytes) / bps / desired.freq); SDL_PauseAudio(0); } while (!end) { while (SDL_PollEvent(&event)) switch (event.type) { case SDL_QUIT: end = 1; break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_q || event.key.keysym.sym == SDLK_ESCAPE) end = 1; break; default: break; } if (have_video && !end) { static double oldt, newt; if (mm_decode_video(&media, ovl) > 0) { SDL_Rect r = { 0, 0, w, h }; newt = 1 / fps + oldt - get_time(); if (newt > 0) SDL_Delay(newt * 1000); SDL_DisplayYUVOverlay(ovl, &r); oldt = get_time(); } else end = 1; } if (have_audio && abuf.bytes <= 0) end = 1; if (!have_video) SDL_Delay(100); } if (have_audio) { SDL_PauseAudio(1); free(abuf.buf); } if (have_video) { SDL_FreeYUVOverlay(ovl); } SDL_Quit(); mm_close(&media); return EXIT_SUCCESS; }
/* rval < 0: error, > 0: have audio or video */ int mm_open_fp(mm_file *mf, FILE *file) { int retval = -1; int res = 0; int have_vorbis = 0; int have_theora = 0; ogg_page pg; assert(mf); memset(mf, 0, sizeof(*mf)); mf->file = file; // This is important. If there is no file // then we need to reset the audio and video // pointers so that the other functions // ignore the file. if (!mf->file) { mf->audio = NULL; mf->video = NULL; return retval; } ogg_sync_init(&mf->sync); /* get first page to start things up */ if (get_page(mf, &pg) <= 0) { goto err; } DEBUG1("trying theora decoder..."); res = init_theora(mf, &pg); if (res < 0) { goto err; } else { have_theora = !!res * MEDIA_VIDEO; } DEBUG1("trying vorbis decoder..."); res = init_vorbis(mf, &pg); if (res < 0) { goto err; } else { have_vorbis = !!res * MEDIA_AUDIO; } if (have_vorbis) { unsigned c = 0, r = 0; mm_audio_info(mf, &c, &r); INFO3("audio %u channel(s) at %u Hz", c, r); } if (have_theora) { unsigned w, h; float fps; mm_video_info(mf, &w, &h, &fps); INFO4("video %ux%u pixels at %g fps", w, h, fps); } return have_vorbis | have_theora; err: WARNING1("unable to decode stream"); mm_close(mf); return retval; }