mirror of https://github.com/odrling/Aegisub
Factor out bounds-checking for GetAudio to a single place
It was being done in inconsistent ways in several places, which did not include all of the places it needed to be done. Closes #1509. Originally committed to SVN as r6960.
This commit is contained in:
parent
037d385419
commit
79684d5ad6
|
@ -88,6 +88,44 @@ void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
||||||
|
if (start+count > num_samples) {
|
||||||
|
int64_t oldcount = count;
|
||||||
|
count = num_samples-start;
|
||||||
|
if (count < 0) count = 0;
|
||||||
|
|
||||||
|
// Fill beyond with zero
|
||||||
|
if (bytes_per_sample == 1) {
|
||||||
|
char *temp = (char *) buf;
|
||||||
|
for (int i=count;i<oldcount;i++) {
|
||||||
|
temp[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bytes_per_sample == 2) {
|
||||||
|
short *temp = (short *) buf;
|
||||||
|
for (int i=count;i<oldcount;i++) {
|
||||||
|
temp[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start + count > num_samples) {
|
||||||
|
int64_t zero_count = std::min(count, start + count - num_samples);
|
||||||
|
count -= zero_count;
|
||||||
|
char *zero_buf = static_cast<char *>(buf) + count * bytes_per_sample * channels;
|
||||||
|
|
||||||
|
if (bytes_per_sample == 1)
|
||||||
|
// 8 bit formats are usually unsigned with bias 127
|
||||||
|
memset(zero_buf, 127, zero_count * channels);
|
||||||
|
else
|
||||||
|
// While everything else is signed
|
||||||
|
memset(zero_buf, 0, zero_count * bytes_per_sample * channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
FillBuffer(buf, start, count);
|
||||||
|
}
|
||||||
|
|
||||||
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int cache) {
|
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int cache) {
|
||||||
AudioProvider *provider = 0;
|
AudioProvider *provider = 0;
|
||||||
bool found_file = false;
|
bool found_file = false;
|
||||||
|
|
|
@ -151,35 +151,7 @@ void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) {
|
||||||
clip = tempclip;
|
clip = tempclip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Get audio
|
void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
/// @param buf
|
clip->GetAudio(buf,start,count,avs_wrapper.GetEnv());
|
||||||
/// @param start
|
|
||||||
/// @param count
|
|
||||||
///
|
|
||||||
void AvisynthAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
|
||||||
// Requested beyond the length of audio
|
|
||||||
if (start+count > num_samples) {
|
|
||||||
int64_t oldcount = count;
|
|
||||||
count = num_samples-start;
|
|
||||||
if (count < 0) count = 0;
|
|
||||||
|
|
||||||
// Fill beyond with zero
|
|
||||||
if (bytes_per_sample == 1) {
|
|
||||||
char *temp = (char *) buf;
|
|
||||||
for (int i=count;i<oldcount;i++) {
|
|
||||||
temp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bytes_per_sample == 2) {
|
|
||||||
short *temp = (short *) buf;
|
|
||||||
for (int i=count;i<oldcount;i++) {
|
|
||||||
temp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count) {
|
|
||||||
clip->GetAudio(buf,start,count,avs_wrapper.GetEnv());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,6 +56,7 @@ class AvisynthAudioProvider : public AudioProvider {
|
||||||
PClip clip;
|
PClip clip;
|
||||||
|
|
||||||
void LoadFromClip(AVSValue clip);
|
void LoadFromClip(AVSValue clip);
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AvisynthAudioProvider(wxString _filename);
|
AvisynthAudioProvider(wxString _filename);
|
||||||
|
@ -64,7 +65,5 @@ public:
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
bool AreSamplesNativeEndian() const { return true; }
|
||||||
bool NeedsCache() const { return true; }
|
bool NeedsCache() const { return true; }
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
bytes_per_sample = sizeof(Target);
|
bytes_per_sample = sizeof(Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const {
|
void FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
std::vector<char> src_buf(count * src_bytes_per_sample * channels);
|
std::vector<char> src_buf(count * src_bytes_per_sample * channels);
|
||||||
source->GetAudio(&src_buf[0], start, count);
|
source->GetAudio(&src_buf[0], start, count);
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ public:
|
||||||
float_samples = false;
|
float_samples = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const {
|
void FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
std::vector<Source> src_buf(count * channels);
|
std::vector<Source> src_buf(count * channels);
|
||||||
source->GetAudio(&src_buf[0], start, count);
|
source->GetAudio(&src_buf[0], start, count);
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ public:
|
||||||
channels = 1;
|
channels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const {
|
void FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
if (count == 0) return;
|
if (count == 0) return;
|
||||||
|
|
||||||
std::vector<int16_t> src_buf(count * src_channels);
|
std::vector<int16_t> src_buf(count * src_channels);
|
||||||
|
@ -187,7 +187,7 @@ public:
|
||||||
num_samples *= 2;
|
num_samples *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const {
|
void FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
if (count == 0) return;
|
if (count == 0) return;
|
||||||
|
|
||||||
int not_end = start + count < num_samples;
|
int not_end = start + count < num_samples;
|
||||||
|
|
|
@ -48,7 +48,7 @@ DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) {
|
||||||
num_samples = (int64_t)dur_ms * sample_rate / 1000;
|
num_samples = (int64_t)dur_ms * sample_rate / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DummyAudioProvider::GetAudio(void *buf, int64_t, int64_t count) const {
|
void DummyAudioProvider::FillBuffer(void *buf, int64_t, int64_t count) const {
|
||||||
short *workbuf = (short*)buf;
|
short *workbuf = (short*)buf;
|
||||||
|
|
||||||
if (noise) {
|
if (noise) {
|
||||||
|
|
|
@ -44,10 +44,10 @@
|
||||||
class DummyAudioProvider : public AudioProvider {
|
class DummyAudioProvider : public AudioProvider {
|
||||||
/// DOCME
|
/// DOCME
|
||||||
bool noise;
|
bool noise;
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DummyAudioProvider(unsigned long dur_ms, bool _noise);
|
DummyAudioProvider(unsigned long dur_ms, bool _noise);
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
bool AreSamplesNativeEndian() const { return true; }
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -175,7 +175,7 @@ void FFmpegSourceAudioProvider::LoadAudio(wxString filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) const {
|
void FFmpegSourceAudioProvider::FillBuffer(void *Buf, int64_t Start, int64_t Count) const {
|
||||||
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) {
|
if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) {
|
||||||
throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer);
|
throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider {
|
||||||
mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages
|
mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages
|
||||||
|
|
||||||
void LoadAudio(wxString filename);
|
void LoadAudio(wxString filename);
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FFmpegSourceAudioProvider(wxString filename);
|
FFmpegSourceAudioProvider(wxString filename);
|
||||||
|
@ -58,7 +59,5 @@ public:
|
||||||
/// FFMS always delivers native endian samples.
|
/// FFMS always delivers native endian samples.
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
bool AreSamplesNativeEndian() const { return true; }
|
||||||
bool NeedsCache() const { return true; }
|
bool NeedsCache() const { return true; }
|
||||||
|
|
||||||
virtual void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -140,7 +140,7 @@ HDAudioProvider::~HDAudioProvider() {
|
||||||
wxRemoveFile(diskCacheFilename);
|
wxRemoveFile(diskCacheFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HDAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
void HDAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
cache_provider->GetAudio(buf, start, count);
|
cache_provider->GetAudio(buf, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,11 @@ class HDAudioProvider : public AudioProvider {
|
||||||
/// @param ps Sink for progress reporting
|
/// @param ps Sink for progress reporting
|
||||||
void FillCache(AudioProvider *src, std::ofstream *file, agi::ProgressSink *ps);
|
void FillCache(AudioProvider *src, std::ofstream *file, agi::ProgressSink *ps);
|
||||||
|
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HDAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
|
HDAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
|
||||||
~HDAudioProvider();
|
~HDAudioProvider();
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
bool AreSamplesNativeEndian() const { return true; }
|
||||||
|
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ LockAudioProvider::LockAudioProvider(AudioProvider *source) : source(source) {
|
||||||
float_samples = source->AreSamplesFloat();
|
float_samples = source->AreSamplesFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LockAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
void LockAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
wxMutexLocker lock(mutex);
|
wxMutexLocker lock(mutex);
|
||||||
source->GetAudio(buf, start, count);
|
source->GetAudio(buf, start, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ class LockAudioProvider : public AudioProvider {
|
||||||
agi::scoped_ptr<const AudioProvider> source;
|
agi::scoped_ptr<const AudioProvider> source;
|
||||||
mutable wxMutex mutex;
|
mutable wxMutex mutex;
|
||||||
|
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
public:
|
public:
|
||||||
LockAudioProvider(AudioProvider *source);
|
LockAudioProvider(AudioProvider *source);
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
|
bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,10 +59,6 @@
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param filename
|
|
||||||
///
|
|
||||||
PCMAudioProvider::PCMAudioProvider(const wxString &filename)
|
PCMAudioProvider::PCMAudioProvider(const wxString &filename)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
: file_handle(0, CloseHandle)
|
: file_handle(0, CloseHandle)
|
||||||
|
@ -117,8 +113,6 @@ PCMAudioProvider::PCMAudioProvider(const wxString &filename)
|
||||||
float_samples = false;
|
float_samples = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
PCMAudioProvider::~PCMAudioProvider()
|
PCMAudioProvider::~PCMAudioProvider()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -130,11 +124,6 @@ PCMAudioProvider::~PCMAudioProvider()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param range_start
|
|
||||||
/// @param range_length
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t range_length) const
|
char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t range_length) const
|
||||||
{
|
{
|
||||||
if (range_start + range_length > file_size) {
|
if (range_start + range_length > file_size) {
|
||||||
|
@ -203,12 +192,7 @@ char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t rang
|
||||||
return ((char*)current_mapping) + rel_ofs;
|
return ((char*)current_mapping) + rel_ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
void PCMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const
|
||||||
/// @param buf
|
|
||||||
/// @param start
|
|
||||||
/// @param count
|
|
||||||
///
|
|
||||||
void PCMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const
|
|
||||||
{
|
{
|
||||||
// Read blocks from the file
|
// Read blocks from the file
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
@ -234,16 +218,6 @@ void PCMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we exhausted all sample sections zerofill the rest
|
|
||||||
if (count > 0) {
|
|
||||||
if (bytes_per_sample == 1)
|
|
||||||
// 8 bit formats are usually unsigned with bias 127
|
|
||||||
memset(buf, 127, count*channels);
|
|
||||||
else
|
|
||||||
// While everything else is signed
|
|
||||||
memset(buf, 0, count*bytes_per_sample*channels);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
|
@ -308,11 +282,8 @@ class RiffWavPCMAudioProvider : public PCMAudioProvider {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param _filename
|
|
||||||
///
|
|
||||||
RiffWavPCMAudioProvider(const wxString &_filename)
|
RiffWavPCMAudioProvider(const wxString &_filename)
|
||||||
: PCMAudioProvider(_filename)
|
: PCMAudioProvider(_filename)
|
||||||
{
|
{
|
||||||
filename = _filename;
|
filename = _filename;
|
||||||
|
|
||||||
|
@ -388,9 +359,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
bool AreSamplesNativeEndian() const
|
bool AreSamplesNativeEndian() const
|
||||||
{
|
{
|
||||||
// 8 bit samples don't consider endianness
|
// 8 bit samples don't consider endianness
|
||||||
|
@ -401,34 +369,26 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static const uint8_t w64GuidRIFF[16] = {
|
static const uint8_t w64GuidRIFF[16] = {
|
||||||
// {66666972-912E-11CF-A5D6-28DB04C10000}
|
// {66666972-912E-11CF-A5D6-28DB04C10000}
|
||||||
0x72, 0x69, 0x66, 0x66, 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
|
0x72, 0x69, 0x66, 0x66, 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static const uint8_t w64GuidWAVE[16] = {
|
static const uint8_t w64GuidWAVE[16] = {
|
||||||
// {65766177-ACF3-11D3-8CD1-00C04F8EDB8A}
|
// {65766177-ACF3-11D3-8CD1-00C04F8EDB8A}
|
||||||
0x77, 0x61, 0x76, 0x65, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
0x77, 0x61, 0x76, 0x65, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static const uint8_t w64Guidfmt[16] = {
|
static const uint8_t w64Guidfmt[16] = {
|
||||||
// {20746D66-ACF3-11D3-8CD1-00C04F8EDB8A}
|
// {20746D66-ACF3-11D3-8CD1-00C04F8EDB8A}
|
||||||
0x66, 0x6D, 0x74, 0x20, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
0x66, 0x6D, 0x74, 0x20, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static const uint8_t w64Guiddata[16] = {
|
static const uint8_t w64Guiddata[16] = {
|
||||||
// {61746164-ACF3-11D3-8CD1-00C04F8EDB8A}
|
// {61746164-ACF3-11D3-8CD1-00C04F8EDB8A}
|
||||||
0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class Wave64AudioProvider
|
/// @class Wave64AudioProvider
|
||||||
/// @brief Sony Wave64 audio provider
|
/// @brief Sony Wave64 audio provider
|
||||||
|
@ -448,49 +408,24 @@ class Wave64AudioProvider : public PCMAudioProvider {
|
||||||
uint16_t cbSize;
|
uint16_t cbSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
struct RiffChunk {
|
struct RiffChunk {
|
||||||
/// DOCME
|
|
||||||
uint8_t riff_guid[16];
|
uint8_t riff_guid[16];
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
uint64_t file_size;
|
uint64_t file_size;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
uint8_t format_guid[16];
|
uint8_t format_guid[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
struct FormatChunk {
|
struct FormatChunk {
|
||||||
/// DOCME
|
|
||||||
uint8_t chunk_guid[16];
|
uint8_t chunk_guid[16];
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
uint64_t chunk_size;
|
uint64_t chunk_size;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
WaveFormatEx format;
|
WaveFormatEx format;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
uint8_t padding[6];
|
uint8_t padding[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
struct DataChunk {
|
struct DataChunk {
|
||||||
/// DOCME
|
|
||||||
uint8_t chunk_guid[16];
|
uint8_t chunk_guid[16];
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
uint64_t chunk_size;
|
uint64_t chunk_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param guid1
|
|
||||||
/// @param guid2
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
inline bool CheckGuid(const uint8_t *guid1, const uint8_t *guid2)
|
inline bool CheckGuid(const uint8_t *guid1, const uint8_t *guid2)
|
||||||
{
|
{
|
||||||
return memcmp(guid1, guid2, 16) == 0;
|
return memcmp(guid1, guid2, 16) == 0;
|
||||||
|
@ -498,9 +433,6 @@ class Wave64AudioProvider : public PCMAudioProvider {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param _filename
|
|
||||||
///
|
|
||||||
Wave64AudioProvider(const wxString &_filename)
|
Wave64AudioProvider(const wxString &_filename)
|
||||||
: PCMAudioProvider(_filename)
|
: PCMAudioProvider(_filename)
|
||||||
{
|
{
|
||||||
|
@ -579,9 +511,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
bool AreSamplesNativeEndian() const
|
bool AreSamplesNativeEndian() const
|
||||||
{
|
{
|
||||||
// 8 bit samples don't consider endianness
|
// 8 bit samples don't consider endianness
|
||||||
|
|
|
@ -57,19 +57,12 @@
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class PCMAudioProvider : public AudioProvider {
|
class PCMAudioProvider : public AudioProvider {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/// DOCME
|
|
||||||
agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> file_handle;
|
agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> file_handle;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> file_mapping;
|
agi::scoped_holder<HANDLE, BOOL (__stdcall *)(HANDLE)> file_mapping;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
mutable void *current_mapping;
|
mutable void *current_mapping;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
mutable int64_t mapping_start;
|
mutable int64_t mapping_start;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
mutable size_t mapping_length;
|
mutable size_t mapping_length;
|
||||||
#else
|
#else
|
||||||
agi::scoped_holder<int, int(*)(int)> file_handle;
|
agi::scoped_holder<int, int(*)(int)> file_handle;
|
||||||
|
@ -83,32 +76,20 @@ protected:
|
||||||
virtual ~PCMAudioProvider(); // Closes the file mapping
|
virtual ~PCMAudioProvider(); // Closes the file mapping
|
||||||
char * EnsureRangeAccessible(int64_t range_start, int64_t range_length) const; // Ensure that the given range of bytes are accessible in the file mapping and return a pointer to the first byte of the requested range
|
char * EnsureRangeAccessible(int64_t range_start, int64_t range_length) const; // Ensure that the given range of bytes are accessible in the file mapping and return a pointer to the first byte of the requested range
|
||||||
|
|
||||||
|
/// Size of the opened file
|
||||||
|
int64_t file_size;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
int64_t file_size; // Size of the opened file
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
struct IndexPoint {
|
struct IndexPoint {
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
int64_t start_byte;
|
int64_t start_byte;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
int64_t start_sample;
|
int64_t start_sample;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
int64_t num_samples;
|
int64_t num_samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
typedef std::vector<IndexPoint> IndexVector;
|
typedef std::vector<IndexPoint> IndexVector;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
IndexVector index_points;
|
IndexVector index_points;
|
||||||
|
|
||||||
public:
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
virtual void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construct the right PCM audio provider (if any) for the file
|
// Construct the right PCM audio provider (if any) for the file
|
||||||
|
|
|
@ -112,45 +112,22 @@ void RAMAudioProvider::Clear() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const {
|
||||||
// Requested beyond the length of audio
|
// Prepare copy
|
||||||
if (start+count > num_samples) {
|
char *charbuf = (char *)buf;
|
||||||
int64_t oldcount = count;
|
int i = (start*bytes_per_sample) >> CacheBits;
|
||||||
count = num_samples-start;
|
int start_offset = (start*bytes_per_sample) & (CacheBlockSize-1);
|
||||||
if (count < 0) count = 0;
|
int64_t bytesremaining = count*bytes_per_sample;
|
||||||
|
|
||||||
// Fill beyond with zero
|
// Copy
|
||||||
if (bytes_per_sample == 1) {
|
while (bytesremaining) {
|
||||||
char *temp = (char *) buf;
|
int readsize = std::min<int>(bytesremaining, CacheBlockSize - start_offset);
|
||||||
for (int i=count;i<oldcount;i++) {
|
|
||||||
temp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bytes_per_sample == 2) {
|
|
||||||
short *temp = (short *) buf;
|
|
||||||
for (int i=count;i<oldcount;i++) {
|
|
||||||
temp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count) {
|
memcpy(charbuf,(char *)(blockcache[i++]+start_offset),readsize);
|
||||||
// Prepare copy
|
|
||||||
char *charbuf = (char *)buf;
|
|
||||||
int i = (start*bytes_per_sample) >> CacheBits;
|
|
||||||
int start_offset = (start*bytes_per_sample) & (CacheBlockSize-1);
|
|
||||||
int64_t bytesremaining = count*bytes_per_sample;
|
|
||||||
|
|
||||||
// Copy
|
charbuf+=readsize;
|
||||||
while (bytesremaining) {
|
|
||||||
int readsize = std::min<int>(bytesremaining, CacheBlockSize - start_offset);
|
|
||||||
|
|
||||||
memcpy(charbuf,(char *)(blockcache[i++]+start_offset),readsize);
|
start_offset=0;
|
||||||
|
bytesremaining-=readsize;
|
||||||
charbuf+=readsize;
|
|
||||||
|
|
||||||
start_offset=0;
|
|
||||||
bytesremaining-=readsize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,11 +58,11 @@ class RAMAudioProvider : public AudioProvider {
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void FillCache(AudioProvider *source, agi::ProgressSink *ps);
|
void FillCache(AudioProvider *source, agi::ProgressSink *ps);
|
||||||
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RAMAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
|
RAMAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
|
||||||
~RAMAudioProvider();
|
~RAMAudioProvider();
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return samples_native_endian; }
|
bool AreSamplesNativeEndian() const { return samples_native_endian; }
|
||||||
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -67,11 +67,13 @@ protected:
|
||||||
/// DOCME
|
/// DOCME
|
||||||
wxString filename;
|
wxString filename;
|
||||||
|
|
||||||
|
virtual void FillBuffer(void *buf, int64_t start, int64_t count) const = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~AudioProvider() { }
|
virtual ~AudioProvider() { }
|
||||||
|
|
||||||
virtual wxString GetFilename() const { return filename; };
|
virtual wxString GetFilename() const { return filename; };
|
||||||
virtual void GetAudio(void *buf, int64_t start, int64_t count) const = 0;
|
void GetAudio(void *buf, int64_t start, int64_t count) const;
|
||||||
void GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const;
|
void GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const;
|
||||||
|
|
||||||
int64_t GetNumSamples() const { return num_samples; }
|
int64_t GetNumSamples() const { return num_samples; }
|
||||||
|
|
Loading…
Reference in New Issue