Finish up XAudio with a round of bugfixes

This commit is contained in:
Ristellise 2022-08-10 21:23:56 +08:00
parent fd28458ed8
commit 994e50048a
6 changed files with 21 additions and 14 deletions

View File

@ -73,7 +73,6 @@ public:
}
namespace agi {
void AudioProvider::FillBufferInt16Mono(int16_t* buf, int64_t start, int64_t count) const {
if (!float_samples && bytes_per_sample == 2 && channels == 1) {
FillBuffer(buf, start, count);
@ -242,7 +241,7 @@ void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int star
out.write("WAVEfmt ");
out.write<int32_t>(16); // Size of chunk
out.write<int16_t>(1); // compression format (PCM)
out.write<int16_t>(provider.AreSamplesFloat() ? 3 : 1); // compression format (1: WAVE_FORMAT_PCM, 3: WAVE_FORMAT_IEEE_FLOAT)
out.write<int16_t>(provider.GetChannels());
out.write<int32_t>(provider.GetSampleRate());
out.write<int32_t>(provider.GetSampleRate() * provider.GetChannels() * provider.GetBytesPerSample());
@ -262,4 +261,4 @@ void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int star
out.write(buf);
}
}
}
}

View File

@ -29,6 +29,11 @@ class LockAudioProvider final : public agi::AudioProviderWrapper {
source->GetAudio(buf, start, count);
}
void FillBufferInt16Mono(int16_t *buf, int64_t start, int64_t count) const override {
std::unique_lock<std::mutex> lock(mutex);
source->GetInt16MonoAudio(buf, start, count);
}
public:
LockAudioProvider(std::unique_ptr<AudioProvider> src)
: AudioProviderWrapper(std::move(src))

View File

@ -46,14 +46,14 @@ public:
decoded_samples = 0;
try {
blockcache.resize((source->GetNumSamples() * source->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
blockcache.resize((num_samples * bytes_per_sample * channels + CacheBlockSize - 1) >> CacheBits);
}
catch (std::bad_alloc const&) {
throw AudioProviderError("Not enough memory available to cache in RAM");
}
decoder = std::thread([&] {
int64_t readsize = CacheBlockSize / source->GetBytesPerSample();
int64_t readsize = CacheBlockSize / bytes_per_sample / channels;
for (size_t i = 0; i < blockcache.size(); i++) {
if (cancelled) break;
auto actual_read = std::min<int64_t>(readsize, num_samples - i * readsize);
@ -95,4 +95,4 @@ namespace agi {
std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvider> src) {
return agi::make_unique<RAMAudioProvider>(std::move(src));
}
}
}

View File

@ -126,8 +126,10 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
// reindex if the error handling mode has changed
FFMS_IndexErrorHandling ErrorHandling = GetErrorHandlingMode();
#if FFMS_VERSION >= ((2 << 24) | (17 << 16) | (2 << 8) | 0)
if (Index && FFMS_GetErrorHandling(Index) != ErrorHandling)
Index = nullptr;
#endif
// moment of truth
if (!Index) {
@ -165,22 +167,23 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
throw agi::AudioProviderError("unknown or unsupported sample format");
}
#if FFMS_VERSION >= ((2 << 24) | (17 << 16) | (4 << 8) | 0)
if (OPT_GET("Provider/Audio/FFmpegSource/Downmix")->GetBool()) {
if (channels > 2 || bytes_per_sample != 2 || float_samples) {
if (channels > 1 || bytes_per_sample != 2 || float_samples) {
std::unique_ptr<FFMS_ResampleOptions, decltype(&FFMS_DestroyResampleOptions)>
opt(FFMS_CreateResampleOptions(AudioSource), FFMS_DestroyResampleOptions);
if (channels > 2)
opt->ChannelLayout = FFMS_CH_FRONT_LEFT | FFMS_CH_FRONT_RIGHT;
opt->ChannelLayout = FFMS_CH_FRONT_CENTER;
opt->SampleFormat = FFMS_FMT_S16;
// Might fail if FFMS2 wasn't built with libavresample
if (!FFMS_SetOutputFormatA(AudioSource, opt.get(), nullptr)) {
channels = channels > 2 ? 2 : channels;
channels = 1;
bytes_per_sample = 2;
float_samples = false;
}
}
}
#endif
}
}
@ -189,4 +192,4 @@ std::unique_ptr<agi::AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::pat
return agi::make_unique<FFmpegSourceAudioProvider>(file, br);
}
#endif /* WITH_FFMS2 */
#endif /* WITH_FFMS2 */

View File

@ -208,8 +208,8 @@ void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block)
assert(block);
int64_t first_sample = (((int64_t)block_index) << derivation_dist) - ((int64_t)1 << derivation_size);
provider->GetAudio(&audio_scratch[0], first_sample, 2 << derivation_size);
provider->GetInt16MonoAudio(audio_scratch.data(), first_sample, 2 << derivation_size);
// Because the FFTs used here are unnormalized DFTs, we have to compensate
// the possible length difference between derivation_size used in the
// calculations and its user-provided counterpart. Thus, the display is

View File

@ -88,7 +88,7 @@ void AudioWaveformRenderer::Render(wxBitmap &bmp, int start, AudioRenderingStyle
for (int x = 0; x < rect.width; ++x)
{
provider->GetAudio(audio_buffer.get(), (int64_t)cur_sample, (int64_t)pixel_samples);
provider->GetInt16MonoAudio(reinterpret_cast<int16_t*>(audio_buffer.get()), (int64_t)cur_sample, (int64_t)pixel_samples);
cur_sample += pixel_samples;
int peak_min = 0, peak_max = 0;