[deploy] pref: estimate the size of ogg file
This commit is contained in:
parent
24368788eb
commit
0f3ab5732d
|
|
@ -55,6 +55,11 @@ struct AudioMeta
|
||||||
uint32_t samples_per_sec = 44100; ///< 采样率,11025 表示 11.025kHz。PCM格式的采样率通常为44.1kHz
|
uint32_t samples_per_sec = 44100; ///< 采样率,11025 表示 11.025kHz。PCM格式的采样率通常为44.1kHz
|
||||||
uint16_t bits_per_sample = 16; ///< 位深,PCM格式为 8 或 16
|
uint16_t bits_per_sample = 16; ///< 位深,PCM格式为 8 或 16
|
||||||
uint16_t block_align = 4; ///< 块对齐,PCM格式通常是 (channels * bits_per_sample) / 8
|
uint16_t block_align = 4; ///< 块对齐,PCM格式通常是 (channels * bits_per_sample) / 8
|
||||||
|
|
||||||
|
inline uint32_t avg_bytes_per_sec() const noexcept
|
||||||
|
{
|
||||||
|
return uint32_t(this->samples_per_sec * this->block_align);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ bool AudioModule::CreateSound(Sound& sound, AudioDataPtr data)
|
||||||
tmp.nSamplesPerSec = DWORD(meta.samples_per_sec);
|
tmp.nSamplesPerSec = DWORD(meta.samples_per_sec);
|
||||||
tmp.wBitsPerSample = WORD(meta.bits_per_sample);
|
tmp.wBitsPerSample = WORD(meta.bits_per_sample);
|
||||||
tmp.nBlockAlign = WORD(meta.block_align);
|
tmp.nBlockAlign = WORD(meta.block_align);
|
||||||
tmp.nAvgBytesPerSec = DWORD(meta.samples_per_sec * meta.block_align);
|
tmp.nAvgBytesPerSec = DWORD(meta.avg_bytes_per_sec());
|
||||||
|
|
||||||
data->SetNative(tmp);
|
data->SetNative(tmp);
|
||||||
wave_fmt = const_cast<WAVEFORMATEX*>(data->GetNative().CastPtr<WAVEFORMATEX>());
|
wave_fmt = const_cast<WAVEFORMATEX*>(data->GetNative().CastPtr<WAVEFORMATEX>());
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ AudioDataPtr OggTranscoder::Decode(const String& file_path)
|
||||||
int err = ov_fopen(file_path.c_str(), &vf);
|
int err = ov_fopen(file_path.c_str(), &vf);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
{
|
{
|
||||||
KGE_ERROR(strings::Format("%s failed (%d): %s", __FUNCTION__, err, "Load audio failed"));
|
KGE_ERROR(strings::Format("%s failed (%d): %s", __FUNCTION__, err, "Open ogg audio failed"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,28 +57,38 @@ AudioDataPtr OggTranscoder::Decode(const String& file_path)
|
||||||
AudioMeta meta;
|
AudioMeta meta;
|
||||||
meta.samples_per_sec = uint32_t(vi->rate);
|
meta.samples_per_sec = uint32_t(vi->rate);
|
||||||
meta.channels = uint16_t(vi->channels);
|
meta.channels = uint16_t(vi->channels);
|
||||||
|
meta.bits_per_sample = uint16_t(16); // the 'word' param of ov_read sets to 2, which means 16-bits samples.
|
||||||
|
meta.block_align = uint16_t(meta.channels * meta.bits_per_sample / 8);
|
||||||
|
|
||||||
|
// Get the audio total duration (in microseconds)
|
||||||
|
auto duration = static_cast<std::uintmax_t>(math::Ceil(ov_time_total(&vf, -1) * 1e6));
|
||||||
|
|
||||||
|
// allocate buffer
|
||||||
|
std::vector<char> data;
|
||||||
|
|
||||||
|
const size_t expected_size = size_t(((duration * meta.avg_bytes_per_sec())) / 1000000) + 1;
|
||||||
|
data.resize(expected_size);
|
||||||
|
|
||||||
// read ogg audio
|
// read ogg audio
|
||||||
size_t buffer_size = 4096;
|
size_t pos = 0;
|
||||||
size_t grow_size = buffer_size;
|
size_t step = 4096;
|
||||||
int bitstream;
|
int bitstream;
|
||||||
|
|
||||||
std::vector<char> data;
|
|
||||||
size_t pos = data.size();
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (data.size() < pos + buffer_size)
|
if (data.size() <= pos)
|
||||||
{
|
{
|
||||||
// allocate buffer
|
data.resize(pos + step);
|
||||||
data.resize(pos + grow_size);
|
|
||||||
if (grow_size < 1024000)
|
|
||||||
{
|
|
||||||
grow_size = size_t(double(grow_size) * 1.25);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const size_t buffer_size = std::min(step, data.size() - pos);
|
||||||
|
|
||||||
int bytes_read = ov_read(&vf, data.data() + pos, int(buffer_size), 0, 2, 1, &bitstream);
|
int bytes_read = ov_read(&vf, data.data() + pos, int(buffer_size), 0, 2, 1, &bitstream);
|
||||||
if (bytes_read <= 0)
|
if (bytes_read == 0)
|
||||||
break;
|
break;
|
||||||
|
if (bytes_read < 0)
|
||||||
|
{
|
||||||
|
KGE_ERROR(strings::Format("%s failed (%d): %s", __FUNCTION__, bytes_read, "Decode ogg audio failed"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
pos += bytes_read;
|
pos += bytes_read;
|
||||||
}
|
}
|
||||||
ov_clear(&vf);
|
ov_clear(&vf);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue