bool AudioProcessor::Reset(int sample_rate, int num_channels) { if (num_channels <= 0) { DEBUG("chromaprint::AudioProcessor::Reset() -- No audio channels."); return false; } if (sample_rate <= kMinSampleRate) { DEBUG("chromaprint::AudioProcessor::Reset() -- Sample rate less than " << kMinSampleRate << " (" << sample_rate << ")."); return false; } m_buffer_offset = 0; if (m_resample_ctx) { av_resample_close(m_resample_ctx); m_resample_ctx = 0; } if (sample_rate != m_target_sample_rate) { m_resample_ctx = av_resample_init( m_target_sample_rate, sample_rate, kResampleFilterLength, kResamplePhaseShift, kResampleLinear, kResampleCutoff); } m_num_channels = num_channels; return true; }
// Initialization and runtime control static int control(struct af_instance_s* af, int cmd, void* arg) { af_resample_t* s = (af_resample_t*)af->setup; af_data_t *data= (af_data_t*)arg; int out_rate, test_output_res; // helpers for checking input format switch(cmd){ case AF_CONTROL_REINIT: if((af->data->rate == data->rate) || (af->data->rate == 0)) return AF_DETACH; af->data->nch = data->nch; if (af->data->nch > AF_NCH) af->data->nch = AF_NCH; af->data->format = AF_FORMAT_S16_NE; af->data->bps = 2; af->mul = (double)af->data->rate / data->rate; af->delay = af->data->nch * s->filter_length / min(af->mul, 1); // *bps*.5 if (s->ctx_out_rate != af->data->rate || s->ctx_in_rate != data->rate || s->ctx_filter_size != s->filter_length || s->ctx_phase_shift != s->phase_shift || s->ctx_linear != s->linear || s->ctx_cutoff != s->cutoff) { if(s->avrctx) av_resample_close(s->avrctx); s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff); s->ctx_out_rate = af->data->rate; s->ctx_in_rate = data->rate; s->ctx_filter_size = s->filter_length; s->ctx_phase_shift = s->phase_shift; s->ctx_linear = s->linear; s->ctx_cutoff = s->cutoff; } // hack to make af_test_output ignore the samplerate change out_rate = af->data->rate; af->data->rate = data->rate; test_output_res = af_test_output(af, (af_data_t*)arg); af->data->rate = out_rate; return test_output_res; case AF_CONTROL_COMMAND_LINE:{ s->cutoff= 0.0; sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff); if(s->cutoff <= 0.0) s->cutoff= max(1.0 - 6.5/(s->filter_length+8), 0.80); return AF_OK; } case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: af->data->rate = *(int*)arg; return AF_OK; } return AF_UNKNOWN; }
int CFfAudioResample::Init( int nInRate, int nOutRate, int nFilterLength, int nLog2PhaseCount, int nLinear, double dCutoff ) {_STT(); // Out with the old Destroy(); // Validate sample rates if ( 0 >= nInRate || 0 >= nOutRate ) return 0; // Build resampling context m_ctx = av_resample_init( nOutRate, nInRate, nFilterLength, nLog2PhaseCount, nLinear, dCutoff ); if ( !m_ctx ) return 0; // Save rates m_nInRate = nInRate; m_nOutRate = nOutRate; return 1; }
static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AVFilterLink *inlink = ctx->inputs[0]; AResampleContext *aresample = ctx->priv; if (aresample->out_rate == -1) aresample->out_rate = outlink->sample_rate; else outlink->sample_rate = aresample->out_rate; outlink->time_base = (AVRational) { 1, aresample->out_rate }; //TODO: make the resampling parameters configurable aresample->resample = av_resample_init(aresample->out_rate, inlink->sample_rate, 16, 10, 0, 0.8); aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; av_log(ctx, AV_LOG_INFO, "r:%"PRId64"Hz -> r:%"PRId64"Hz\n", inlink->sample_rate, outlink->sample_rate); return 0; }
void BE_ST_InitAudio(void) { g_sdlAudioSubsystemUp = false; g_sdlEmulatedOPLChipReady = false; int inSampleRate = BE_Cross_GetSelectedGameVerSampleRate(); bool doDigitized = (inSampleRate != 0); if (!doDigitized) inSampleRate = OPL_SAMPLE_RATE; if (g_refKeenCfg.sndSubSystem) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "SDL audio system initialization failed,\n%s\n", SDL_GetError()); } else { g_sdlAudioSpec.freq = g_refKeenCfg.sndSampleRate; #ifdef MIXER_SAMPLE_FORMAT_FLOAT g_sdlAudioSpec.format = AUDIO_F32SYS; #elif (defined MIXER_SAMPLE_FORMAT_SINT16) g_sdlAudioSpec.format = AUDIO_S16SYS; #endif g_sdlAudioSpec.channels = 1; // Should be some power-of-two roughly proportional to the sample rate; Using 1024 for 48000Hz. for (g_sdlAudioSpec.samples = 1; g_sdlAudioSpec.samples < g_refKeenCfg.sndSampleRate/64; g_sdlAudioSpec.samples *= 2) { } if (doDigitized) g_sdlAudioSpec.callback = (g_refKeenCfg.sndSampleRate == inSampleRate) ? BEL_ST_Simple_DigiCallBack : BEL_ST_Resampling_DigiCallBack; else g_sdlAudioSpec.callback = ((g_refKeenCfg.sndSampleRate == inSampleRate) || !g_refKeenCfg.oplEmulation) ? BEL_ST_Simple_EmuCallBack : BEL_ST_Resampling_EmuCallBack; g_sdlAudioSpec.userdata = NULL; if (SDL_OpenAudio(&g_sdlAudioSpec, NULL)) { BE_Cross_LogMessage(BE_LOG_MSG_WARNING, "Cannot open SDL audio device,\n%s\n", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else { #ifdef REFKEEN_CONFIG_THREADS g_sdlCallbackMutex = SDL_CreateMutex(); if (!g_sdlCallbackMutex) { BE_Cross_LogMessage(BE_LOG_MSG_ERROR, "Cannot create recursive mutex for SDL audio callback,\n%s\nClosing SDL audio subsystem\n", SDL_GetError()); SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); } else #endif { BE_Cross_LogMessage(BE_LOG_MSG_NORMAL, "Audio subsystem initialized, requested spec: freq %d, format %u, channels %d, samples %u\n", (int)g_sdlAudioSpec.freq, (unsigned int)g_sdlAudioSpec.format, (int)g_sdlAudioSpec.channels, (unsigned int)g_sdlAudioSpec.samples); g_sdlAudioSubsystemUp = true; } } } } // If the audio subsystem is off, let us simulate a byte rate // of 1000Hz (same as SDL_GetTicks() time units) if (!g_sdlAudioSubsystemUp) { g_sdlAudioSpec.freq = doDigitized ? inSampleRate : (NUM_OF_BYTES_FOR_SOUND_CALLBACK_WITH_DISABLED_SUBSYSTEM / sizeof(BE_ST_SndSample_T)); g_sdlAudioSpec.callback = doDigitized ? BEL_ST_Resampling_DigiCallBack : BEL_ST_Resampling_EmuCallBack; return; } if (g_refKeenCfg.oplEmulation) { YM3812Init(1, 3579545, OPL_SAMPLE_RATE); g_sdlEmulatedOPLChipReady = true; } if ((doDigitized || g_sdlEmulatedOPLChipReady) && (g_sdlAudioSpec.freq != inSampleRate)) { // Should allocate this first, for g_sdlSrcData.data_in g_sdlMiscOutNumOfSamples = 2*g_sdlAudioSpec.samples; g_sdlMiscOutSamples = (BE_ST_SndSample_T *)malloc(sizeof(BE_ST_SndSample_T) * g_sdlMiscOutNumOfSamples); if (g_sdlMiscOutSamples == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Out of memory! (Failed to allocate g_sdlMiscOutSamples.)"); #ifndef REFKEEN_RESAMPLER_NONE if (g_refKeenCfg.useResampler) { #if (!defined REFKEEN_RESAMPLER_LIBRESAMPLE) && (!defined REFKEEN_RESAMPLER_LIBAVCODEC) char errMsg[160]; #endif #if (defined REFKEEN_RESAMPLER_LIBSWRESAMPLE) g_sdlSwrContext = swr_alloc_set_opts( NULL, // allocating a new context AV_CH_LAYOUT_MONO, // out channels layout AV_SAMPLE_FMT_S16, // out format g_sdlAudioSpec.freq, // out rate AV_CH_LAYOUT_MONO, // in channels layout AV_SAMPLE_FMT_S16, // in format inSampleRate, // in rate 0, NULL ); if (g_sdlSwrContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: swr_alloc_set_opts failed!"); int error = swr_init(g_sdlSwrContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVRESAMPLE) g_sdlAvAudioResampleContext = avresample_alloc_context(); if (g_sdlAvAudioResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: avresample_alloc_context failed!"); av_opt_set_int(g_sdlAvAudioResampleContext, "in_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_channel_layout", AV_CH_LAYOUT_MONO, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_rate", inSampleRate, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_rate", g_sdlAudioSpec.freq, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(g_sdlAvAudioResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); int error = avresample_open(g_sdlAvAudioResampleContext); if (error != 0) { // av_err2str requires libavutil/libavutil-ffmpeg, so don't convert code to string snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: swr_init failed! Error code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBAVCODEC) avcodec_register_all(); g_sdlAvResampleContext = av_resample_init( g_sdlAudioSpec.freq, // out rate inSampleRate, // in rate 16, // filter length 10, // phase count 0, // linear FIR filter 1.0 // cutoff frequency ); if (g_sdlAvResampleContext == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: av_resample_init failed!"); #elif (defined REFKEEN_RESAMPLER_LIBRESAMPLE) g_sdlResampleFactor = (double)g_sdlAudioSpec.freq/inSampleRate; g_sdlResampleHandle = resample_open(0, g_sdlResampleFactor, g_sdlResampleFactor); if (g_sdlResampleHandle == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: resample_open failed!"); #elif (defined REFKEEN_RESAMPLER_LIBSOXR) soxr_io_spec_t io_spec = soxr_io_spec(SOXR_INT16, SOXR_INT16); soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LQ, 0); // Default quality spec adds an audible latency for resampling to 8000Hz soxr_error_t error; g_sdlSoxr = soxr_create( inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 1, // channels &error, &io_spec, &q_spec, NULL // runtime spec ); if (g_sdlSoxr == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: soxr_create failed!\nError: %s", soxr_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSPEEXDSP) int error; g_sdlSpeexResamplerState = speex_resampler_init( 1, // channels inSampleRate, // in rate g_sdlAudioSpec.freq, // out rate 0, // quality in the range 0-10 (10 is higher) &error ); if (g_sdlSpeexResamplerState == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: speex_resampler_init failed! Error code: %d\nError: %s", error, speex_resampler_strerror(error)); BE_ST_ExitWithErrorMsg(errMsg); } #elif (defined REFKEEN_RESAMPLER_LIBSAMPLERATE) int error; g_sdlSrcResampler = src_new(SRC_SINC_FASTEST, 1, &error); if (g_sdlSrcResampler == NULL) { snprintf(errMsg, sizeof(errMsg), "BE_ST_InitAudio: src_new failed!\nError code: %d", error); BE_ST_ExitWithErrorMsg(errMsg); } g_sdlSrcData.data_in = doDigitized ? g_sdlMiscOutSamples : g_sdlALOutSamples; g_sdlSrcData.src_ratio = (double)g_sdlAudioSpec.freq / inSampleRate; #endif } else #endif // REFKEEN_RESAMPLER_NONE { // The sum of all entries should be g_sdlAudioSpec.freq, // "uniformly" distributed over g_sdlALSampleRateConvTable g_sdlSampleRateConvTable = (int *)malloc(sizeof(int) * inSampleRate); if (g_sdlSampleRateConvTable == NULL) BE_ST_ExitWithErrorMsg("BE_ST_InitAudio: Failed to allocate memory for sample rate conversion!"); g_sdlSampleRateConvTableSize = inSampleRate; for (int i = 0; i < inSampleRate; ++i) { // Using uint64_t cause an overflow is possible g_sdlSampleRateConvTable[i] = ((uint64_t)(i+1)*(uint64_t)g_sdlAudioSpec.freq/inSampleRate)-(uint64_t)i*(uint64_t)g_sdlAudioSpec.freq/inSampleRate; } g_sdlSampleRateConvCurrIndex = 0; g_sdlSampleRateConvCounter = 0; } } }