Handle channel > 1 in hd & ram cache audio provider

This commit is contained in:
wangqr 2019-10-30 00:47:45 -04:00
parent c1a4e0674b
commit 620033915a
2 changed files with 12 additions and 12 deletions

View file

@ -38,20 +38,20 @@ class HDAudioProvider final : public AudioProviderWrapper {
void FillBuffer(void *buf, int64_t start, int64_t count) const override {
auto missing = std::min(count, start + count - decoded_samples);
if (missing > 0) {
memset(static_cast<int16_t*>(buf) + count - missing, 0, missing * bytes_per_sample);
memset(static_cast<int16_t*>(buf) + count - missing, 0, missing * bytes_per_sample * channels);
count -= missing;
}
if (count > 0) {
start *= bytes_per_sample;
count *= bytes_per_sample;
start *= bytes_per_sample * channels;
count *= bytes_per_sample * channels;
memcpy(buf, file.read(start, count), count);
}
}
fs::path CacheFilename(fs::path const& dir) {
// Check free space
if ((uint64_t)num_samples * bytes_per_sample > fs::FreeSpace(dir))
if ((uint64_t)num_samples * bytes_per_sample * channels > fs::FreeSpace(dir))
throw AudioProviderError("Not enough free disk space in " + dir.string() + " to cache the audio");
return format("audio-%lld-%lld", time(nullptr),
@ -61,7 +61,7 @@ class HDAudioProvider final : public AudioProviderWrapper {
public:
HDAudioProvider(std::unique_ptr<AudioProvider> src, agi::fs::path const& dir)
: AudioProviderWrapper(std::move(src))
, file(dir / CacheFilename(dir), num_samples * bytes_per_sample)
, file(dir / CacheFilename(dir), num_samples * bytes_per_sample* channels)
{
decoded_samples = 0;
decoder = std::thread([&] {
@ -69,7 +69,7 @@ public:
for (int64_t i = 0; i < num_samples; i += block) {
if (cancelled) break;
block = std::min(block, num_samples - i);
source->GetAudio(file.write(i * bytes_per_sample, block * bytes_per_sample), i, block);
source->GetAudio(file.write(i * bytes_per_sample * channels, block * bytes_per_sample * channels), i, block);
decoded_samples += block;
}
});

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);
@ -71,20 +71,20 @@ public:
void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
auto charbuf = static_cast<char *>(buf);
for (int64_t bytes_remaining = count * bytes_per_sample; bytes_remaining; ) {
for (int64_t bytes_remaining = count * bytes_per_sample * channels; bytes_remaining; ) {
if (start >= decoded_samples) {
memset(charbuf, 0, bytes_remaining);
break;
}
const size_t i = (start * bytes_per_sample) >> CacheBits;
const int start_offset = (start * bytes_per_sample) & (CacheBlockSize-1);
const size_t i = (start * bytes_per_sample * channels) >> CacheBits;
const int start_offset = (start * bytes_per_sample * channels) & (CacheBlockSize-1);
const int read_size = std::min<int>(bytes_remaining, CacheBlockSize - start_offset);
memcpy(charbuf, &blockcache[i][start_offset], read_size);
charbuf += read_size;
bytes_remaining -= read_size;
start += read_size / bytes_per_sample;
start += read_size / bytes_per_sample / channels;
}
}
}