From dd1ded06713efbd7be10b9dedbe96fbaa3149f00 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Fri, 25 Jan 2008 20:53:12 +0000 Subject: [PATCH] Made audio provider converter able to convert from 22 kHz Originally committed to SVN as r1833. --- aegisub/audio_display.cpp | 32 +++++---- aegisub/audio_provider.cpp | 4 +- aegisub/audio_provider_convert.cpp | 107 +++++++++++++++++++++++++---- aegisub/audio_provider_convert.h | 4 ++ 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/aegisub/audio_display.cpp b/aegisub/audio_display.cpp index f02abe4d1..1b3a3058e 100644 --- a/aegisub/audio_display.cpp +++ b/aegisub/audio_display.cpp @@ -792,21 +792,23 @@ void AudioDisplay::SetSamplesPercent(int percent,bool update,float pivot) { void AudioDisplay::UpdateSamples() { // Set samples if (!provider) return; - int64_t totalSamples = provider->GetNumSamples(); - int total = totalSamples / w; - int max = 5760000 / w; // 2 minutes at 48 kHz maximum - if (total > max) total = max; - int min = 8; - if (total < min) total = min; - int range = total-min; - samples = int(range*pow(samplesPercent/100.0,3)+min); + if (w) { + int64_t totalSamples = provider->GetNumSamples(); + int total = totalSamples / w; + int max = 5760000 / w; // 2 minutes at 48 kHz maximum + if (total > max) total = max; + int min = 8; + if (total < min) total = min; + int range = total-min; + samples = int(range*pow(samplesPercent/100.0,3)+min); - // Set position - int length = w * samples; - if (PositionSample + length > totalSamples) { - PositionSample = totalSamples - length; - if (PositionSample < 0) PositionSample = 0; - Position = PositionSample / samples; + // Set position + int length = w * samples; + if (PositionSample + length > totalSamples) { + PositionSample = totalSamples - length; + if (PositionSample < 0) PositionSample = 0; + if (samples) Position = PositionSample / samples; + } } } @@ -1915,8 +1917,8 @@ void AudioDisplay::OnSize(wxSizeEvent &event) { h -= Options.AsBool(_T("Audio Draw Timeline")) ? 20 : 0; // Update image + UpdateSamples(); if (samples) { - UpdateSamples(); UpdatePosition(PositionSample / samples); } UpdateImage(); diff --git a/aegisub/audio_provider.cpp b/aegisub/audio_provider.cpp index af6ee865b..debf69074 100644 --- a/aegisub/audio_provider.cpp +++ b/aegisub/audio_provider.cpp @@ -192,7 +192,7 @@ AudioProvider *AudioProviderFactory::GetAudioProvider(wxString filename, int cac // Try a PCM provider first provider = CreatePCMAudioProvider(filename); if (provider) { - if (provider->GetBytesPerSample() == 2) return provider; + if (provider->GetBytesPerSample() == 2 && provider->GetSampleRate() >= 32000) return provider; return new ConvertAudioProvider(provider); } @@ -221,7 +221,7 @@ AudioProvider *AudioProviderFactory::GetAudioProvider(wxString filename, int cac if (!provider) throw error; // Give it a conversor if needed - if (provider->GetBytesPerSample() != 2) provider = new ConvertAudioProvider(provider); + if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000) provider = new ConvertAudioProvider(provider); // Change provider to RAM/HD cache if needed if (cache == -1) cache = Options.AsInt(_T("Audio Cache")); diff --git a/aegisub/audio_provider_convert.cpp b/aegisub/audio_provider_convert.cpp index 0eb778f32..f91c957b0 100644 --- a/aegisub/audio_provider_convert.cpp +++ b/aegisub/audio_provider_convert.cpp @@ -50,6 +50,12 @@ ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) { num_samples = source->GetNumSamples(); sample_rate = source->GetSampleRate(); bytes_per_sample = 2; + + sampleMult = 1; + if (sample_rate < 16000) sampleMult = 4; + else if (sample_rate < 32000) sampleMult = 2; + sample_rate *= sampleMult; + num_samples *= sampleMult; } @@ -60,28 +66,99 @@ ConvertAudioProvider::~ConvertAudioProvider() { } +///////////////////// +// Convert to 16-bit +void ConvertAudioProvider::Make16Bit(const char *src, short *dst, int64_t count) { + for (int64_t i=0;iGetBytesPerSample(); - // Convert from 8-bit to 16-bit - if (srcBps == 1) { - unsigned char *buffer = new unsigned char[count]; - source->GetAudio(buffer,start,count); - short temp; - short *dst = (short*) destination; - for (int64_t i=0;iGetAudio(destination,start,count); } - // No conversion needed - else if (srcBps == 2) source->GetAudio(destination,start,count); + // Convert + else { + // Allocate buffers with sufficient size for the entire operation + size_t fullSize = count; + int64_t srcCount = count / sampleMult; + short *buffer1 = NULL; + short *buffer2 = NULL; + short *last = NULL; - // Unsupported - else throw _T("Unknown bits per sample value."); + // Read audio + buffer1 = new short[fullSize]; + source->GetAudio(buffer1,start/sampleMult,srcCount); + + // Convert from 8-bit to 16-bit + if (srcBps == 1) { + if (sampleMult == 1) { + Make16Bit((const char*)buffer1,(short*)destination,srcCount); + } + else { + buffer2 = new short[fullSize]; + Make16Bit((const char*)buffer1,buffer2,srcCount); + last = buffer2; + } + } + + // Already 16-bit + else if (srcBps == 2) last = buffer1; + + // Convert sample rate + if (sampleMult != 1) { + ChangeSampleRate(last,(short*)destination,count); + } + + delete [] buffer1; + delete [] buffer2; + } } diff --git a/aegisub/audio_provider_convert.h b/aegisub/audio_provider_convert.h index 60f4f8429..d88448650 100644 --- a/aegisub/audio_provider_convert.h +++ b/aegisub/audio_provider_convert.h @@ -46,7 +46,11 @@ // Audio provider class class ConvertAudioProvider : public AudioProvider { private: + int sampleMult; + AudioProvider *source; + void Make16Bit(const char *src, short *dst, int64_t count); + void ChangeSampleRate(const short *src, short *dst, int64_t count); public: ConvertAudioProvider(AudioProvider *source);