mirror of https://github.com/odrling/Aegisub
Finish up XAudio with a round of bugfixes
This commit is contained in:
parent
fd28458ed8
commit
994e50048a
|
@ -73,7 +73,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace agi {
|
namespace agi {
|
||||||
|
|
||||||
void AudioProvider::FillBufferInt16Mono(int16_t* buf, int64_t start, int64_t count) const {
|
void AudioProvider::FillBufferInt16Mono(int16_t* buf, int64_t start, int64_t count) const {
|
||||||
if (!float_samples && bytes_per_sample == 2 && channels == 1) {
|
if (!float_samples && bytes_per_sample == 2 && channels == 1) {
|
||||||
FillBuffer(buf, start, count);
|
FillBuffer(buf, start, count);
|
||||||
|
@ -242,7 +241,7 @@ void SaveAudioClip(AudioProvider const& provider, fs::path const& path, int star
|
||||||
|
|
||||||
out.write("WAVEfmt ");
|
out.write("WAVEfmt ");
|
||||||
out.write<int32_t>(16); // Size of chunk
|
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<int16_t>(provider.GetChannels());
|
||||||
out.write<int32_t>(provider.GetSampleRate());
|
out.write<int32_t>(provider.GetSampleRate());
|
||||||
out.write<int32_t>(provider.GetSampleRate() * provider.GetChannels() * provider.GetBytesPerSample());
|
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);
|
out.write(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,6 +29,11 @@ class LockAudioProvider final : public agi::AudioProviderWrapper {
|
||||||
source->GetAudio(buf, start, count);
|
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:
|
public:
|
||||||
LockAudioProvider(std::unique_ptr<AudioProvider> src)
|
LockAudioProvider(std::unique_ptr<AudioProvider> src)
|
||||||
: AudioProviderWrapper(std::move(src))
|
: AudioProviderWrapper(std::move(src))
|
||||||
|
|
|
@ -46,14 +46,14 @@ public:
|
||||||
decoded_samples = 0;
|
decoded_samples = 0;
|
||||||
|
|
||||||
try {
|
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&) {
|
catch (std::bad_alloc const&) {
|
||||||
throw AudioProviderError("Not enough memory available to cache in RAM");
|
throw AudioProviderError("Not enough memory available to cache in RAM");
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder = std::thread([&] {
|
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++) {
|
for (size_t i = 0; i < blockcache.size(); i++) {
|
||||||
if (cancelled) break;
|
if (cancelled) break;
|
||||||
auto actual_read = std::min<int64_t>(readsize, num_samples - i * readsize);
|
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) {
|
std::unique_ptr<AudioProvider> CreateRAMAudioProvider(std::unique_ptr<AudioProvider> src) {
|
||||||
return agi::make_unique<RAMAudioProvider>(std::move(src));
|
return agi::make_unique<RAMAudioProvider>(std::move(src));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -126,8 +126,10 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
|
||||||
|
|
||||||
// reindex if the error handling mode has changed
|
// reindex if the error handling mode has changed
|
||||||
FFMS_IndexErrorHandling ErrorHandling = GetErrorHandlingMode();
|
FFMS_IndexErrorHandling ErrorHandling = GetErrorHandlingMode();
|
||||||
|
#if FFMS_VERSION >= ((2 << 24) | (17 << 16) | (2 << 8) | 0)
|
||||||
if (Index && FFMS_GetErrorHandling(Index) != ErrorHandling)
|
if (Index && FFMS_GetErrorHandling(Index) != ErrorHandling)
|
||||||
Index = nullptr;
|
Index = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
// moment of truth
|
// moment of truth
|
||||||
if (!Index) {
|
if (!Index) {
|
||||||
|
@ -165,22 +167,23 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) {
|
||||||
throw agi::AudioProviderError("unknown or unsupported sample format");
|
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 (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)>
|
std::unique_ptr<FFMS_ResampleOptions, decltype(&FFMS_DestroyResampleOptions)>
|
||||||
opt(FFMS_CreateResampleOptions(AudioSource), FFMS_DestroyResampleOptions);
|
opt(FFMS_CreateResampleOptions(AudioSource), FFMS_DestroyResampleOptions);
|
||||||
if (channels > 2)
|
opt->ChannelLayout = FFMS_CH_FRONT_CENTER;
|
||||||
opt->ChannelLayout = FFMS_CH_FRONT_LEFT | FFMS_CH_FRONT_RIGHT;
|
|
||||||
opt->SampleFormat = FFMS_FMT_S16;
|
opt->SampleFormat = FFMS_FMT_S16;
|
||||||
|
|
||||||
// Might fail if FFMS2 wasn't built with libavresample
|
// Might fail if FFMS2 wasn't built with libavresample
|
||||||
if (!FFMS_SetOutputFormatA(AudioSource, opt.get(), nullptr)) {
|
if (!FFMS_SetOutputFormatA(AudioSource, opt.get(), nullptr)) {
|
||||||
channels = channels > 2 ? 2 : channels;
|
channels = 1;
|
||||||
bytes_per_sample = 2;
|
bytes_per_sample = 2;
|
||||||
float_samples = false;
|
float_samples = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -189,4 +192,4 @@ std::unique_ptr<agi::AudioProvider> CreateFFmpegSourceAudioProvider(agi::fs::pat
|
||||||
return agi::make_unique<FFmpegSourceAudioProvider>(file, br);
|
return agi::make_unique<FFmpegSourceAudioProvider>(file, br);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_FFMS2 */
|
#endif /* WITH_FFMS2 */
|
|
@ -208,8 +208,8 @@ void AudioSpectrumRenderer::FillBlock(size_t block_index, float *block)
|
||||||
assert(block);
|
assert(block);
|
||||||
|
|
||||||
int64_t first_sample = (((int64_t)block_index) << derivation_dist) - ((int64_t)1 << derivation_size);
|
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
|
// Because the FFTs used here are unnormalized DFTs, we have to compensate
|
||||||
// the possible length difference between derivation_size used in the
|
// the possible length difference between derivation_size used in the
|
||||||
// calculations and its user-provided counterpart. Thus, the display is
|
// calculations and its user-provided counterpart. Thus, the display is
|
||||||
|
|
|
@ -88,7 +88,7 @@ void AudioWaveformRenderer::Render(wxBitmap &bmp, int start, AudioRenderingStyle
|
||||||
|
|
||||||
for (int x = 0; x < rect.width; ++x)
|
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;
|
cur_sample += pixel_samples;
|
||||||
|
|
||||||
int peak_min = 0, peak_max = 0;
|
int peak_min = 0, peak_max = 0;
|
||||||
|
|
Loading…
Reference in New Issue