📄 audio.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / SDL audio and video module * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "sdl_out.h"#define SDLAUD() SDLAudCtx *ctx = (SDLAudCtx *)dr->opaquevoid sdl_fill_audio(void *udata, Uint8 *stream, int len){ GF_AudioOutput *dr = (GF_AudioOutput *)udata; dr->FillBuffer(dr->audio_renderer, stream, len); }static GF_Err SDLAud_Setup(GF_AudioOutput *dr, void *os_handle, u32 num_buffers, u32 total_duration){ u32 flags; SDL_AudioSpec want_format, got_format; SDLAUD(); /*init sdl*/ if (!SDLOUT_InitSDL()) return GF_IO_ERR; flags = SDL_WasInit(SDL_INIT_AUDIO); if (!(flags & SDL_INIT_AUDIO)) { if (SDL_InitSubSystem(SDL_INIT_AUDIO)<0) { SDLOUT_CloseSDL(); return GF_IO_ERR; } } /*check we can open the device*/ memset(&want_format, 0, sizeof(SDL_AudioSpec)); want_format.freq = 44100; want_format.format = AUDIO_S16SYS; want_format.channels = 2; want_format.samples = 1024; want_format.callback = sdl_fill_audio; want_format.userdata = dr; if ( SDL_OpenAudio(&want_format, &got_format) < 0 ) { SDL_QuitSubSystem(SDL_INIT_AUDIO); SDLOUT_CloseSDL(); return GF_IO_ERR; } SDL_CloseAudio(); ctx->is_init = 1; ctx->num_buffers = num_buffers; ctx->total_duration = total_duration; return GF_OK;}static void SDLAud_Shutdown(GF_AudioOutput *dr){ SDLAUD(); if (ctx->is_running) SDL_CloseAudio(); if (ctx->is_init) { SDL_QuitSubSystem(SDL_INIT_AUDIO); SDLOUT_CloseSDL(); ctx->is_init = 0; }}static GF_Err SDLAud_ConfigureOutput(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbChannels, u32 *nbBitsPerSample, u32 channel_cfg){ s32 nb_samples; SDL_AudioSpec want_format, got_format; SDLAUD(); if (ctx->is_running) SDL_CloseAudio(); ctx->is_running = 0; memset(&want_format, 0, sizeof(SDL_AudioSpec)); want_format.freq = *SampleRate; want_format.format = (*nbBitsPerSample==16) ? AUDIO_S16SYS : AUDIO_S8; want_format.channels = *NbChannels; want_format.callback = sdl_fill_audio; want_format.userdata = dr; if (ctx->num_buffers && ctx->total_duration) { nb_samples = want_format.freq * ctx->total_duration; nb_samples /= (1000 * ctx->num_buffers); if (nb_samples % 2) nb_samples++; } else { nb_samples = 1024; } /*respect SDL need for power of 2*/ want_format.samples = 1; while (want_format.samples*2<nb_samples) want_format.samples *= 2; if ( SDL_OpenAudio(&want_format, &got_format) < 0 ) return GF_IO_ERR; ctx->is_running = 1; ctx->delay_ms = (got_format.samples * 1000) / got_format.freq; ctx->total_size = got_format.samples; *SampleRate = got_format.freq; *NbChannels = got_format.channels; switch (got_format.format) { case AUDIO_S8: case AUDIO_U8: *nbBitsPerSample = 8; break; default: *nbBitsPerSample = 16; break; } /*and play*/ SDL_PauseAudio(0); return GF_OK;}static u32 SDLAud_GetAudioDelay(GF_AudioOutput *dr){ SDLAUD(); return ctx->delay_ms;}static u32 SDLAud_GetTotalBufferTime(GF_AudioOutput *dr){ SDLAUD(); return ctx->delay_ms;}static void SDLAud_SetVolume(GF_AudioOutput *dr, u32 Volume){ /*not supported by SDL*/}static void SDLAud_SetPan(GF_AudioOutput *dr, u32 pan){ /*not supported by SDL*/}static void SDLAud_Play(GF_AudioOutput *dr, u32 PlayType){ SDL_PauseAudio(PlayType ? 0 : 1);}static void SDLAud_SetPriority(GF_AudioOutput *dr, u32 priority){ /*not supported by SDL*/}static GF_Err SDLAud_QueryOutputSampleRate(GF_AudioOutput *dr, u32 *desired_samplerate, u32 *NbChannels, u32 *nbBitsPerSample){ /*cannot query supported formats in SDL...*/ return GF_OK;}void *SDL_NewAudio(){ SDLAudCtx *ctx; GF_AudioOutput *dr; ctx = malloc(sizeof(SDLAudCtx)); memset(ctx, 0, sizeof(SDLAudCtx)); dr = malloc(sizeof(GF_AudioOutput)); memset(dr, 0, sizeof(GF_AudioOutput)); GF_REGISTER_MODULE_INTERFACE(dr, GF_AUDIO_OUTPUT_INTERFACE, "SDL Audio Output", "gpac distribution"); dr->opaque = ctx; dr->Setup = SDLAud_Setup; dr->Shutdown = SDLAud_Shutdown; dr->ConfigureOutput = SDLAud_ConfigureOutput; dr->SetVolume = SDLAud_SetVolume; dr->SetPan = SDLAud_SetPan; dr->Play = SDLAud_Play; dr->SetPriority = SDLAud_SetPriority; dr->GetAudioDelay = SDLAud_GetAudioDelay; dr->GetTotalBufferTime = SDLAud_GetTotalBufferTime; dr->QueryOutputSampleRate = SDLAud_QueryOutputSampleRate; /*always threaded*/ dr->SelfThreaded = 1; return dr;}void SDL_DeleteAudio(void *ifce){ GF_AudioOutput *dr = (GF_AudioOutput*)ifce; SDLAUD(); free(ctx); free(ifce);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -