movies: Update FLAC decoder

- Modernized FlacAudio implementation using updated dr_flac APIs.
- Fixed Interrogate syntax error in dr_flac.h by guarding MSVC-specific __int64 types with !defined(CPPPARSER).
- Updated FlacAudioCursor to use PCM frame-based read and seek methods.
- Implemented required callbacks (cb_tell_proc) for modern dr_flac support.

Fixes #1570
Closes #1791
This commit is contained in:
TRIGON69 2025-12-28 21:32:07 +05:30 committed by rdb
parent e918eff231
commit 585c58198a
3 changed files with 11790 additions and 2092 deletions

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
class FlacAudioCursor;
/**
* Reads FLAC audio files. Ogg-encapsulated FLAC files are not supported.
* Reads FLAC audio files. Ogg-encapsulated FLAC files are now supported.
*
* @since 1.10.0
*/

View File

@ -26,7 +26,7 @@ extern "C" {
*/
static size_t cb_read_proc(void *user, void *buffer, size_t size) {
std::istream *stream = (std::istream *)user;
nassertr(stream != nullptr, false);
nassertr(stream != nullptr, 0);
stream->read((char *)buffer, size);
@ -39,14 +39,37 @@ static size_t cb_read_proc(void *user, void *buffer, size_t size) {
}
/**
* Callback passed to dr_flac to implement file I/O via the VirtualFileSystem.
* Callback passed to dr_flac to implement file seeking via the VirtualFileSystem.
*/
static bool cb_seek_proc(void *user, int offset) {
std::istream *stream = (std::istream *)user;
nassertr(stream != nullptr, false);
static drflac_bool32 cb_seek_proc(void* user, int offset, drflac_seek_origin origin) {
std::istream* stream = static_cast<std::istream*>(user);
nassertr(stream != nullptr, DRFLAC_FALSE);
stream->seekg(offset, std::ios::cur);
return !stream->fail();
std::ios_base::seekdir dir;
switch (origin) {
case DRFLAC_SEEK_SET:
dir = std::ios_base::beg;
break;
case DRFLAC_SEEK_CUR:
dir = std::ios_base::cur;
break;
default:
return DRFLAC_FALSE;
}
stream->seekg(offset, dir);
return !stream->fail() ? DRFLAC_TRUE : DRFLAC_FALSE;
}
/**
* Callback passed to dr_flac to report the current stream position.
*/
static drflac_bool32 cb_tell_proc(void *user, drflac_int64 *pCursor) {
std::istream *stream = (std::istream *)user;
nassertr(stream != nullptr, DRFLAC_FALSE);
*pCursor = (drflac_int64)stream->tellg();
return !stream->fail() ? DRFLAC_TRUE : DRFLAC_FALSE;
}
TypeHandle FlacAudioCursor::_type_handle;
@ -65,7 +88,7 @@ FlacAudioCursor(FlacAudio *src, std::istream *stream) :
nassertv(stream != nullptr);
nassertv(stream->good());
_drflac = drflac_open(&cb_read_proc, &cb_seek_proc, (void *)stream);
_drflac = drflac_open(&cb_read_proc, &cb_seek_proc, &cb_tell_proc, (void *)stream, nullptr);
if (_drflac == nullptr) {
movies_cat.error()
@ -73,7 +96,7 @@ FlacAudioCursor(FlacAudio *src, std::istream *stream) :
_is_valid = false;
}
_length = (_drflac->totalSampleCount / _drflac->channels) / (double)_drflac->sampleRate;
_length = _drflac->totalPCMFrameCount / (double)_drflac->sampleRate;
_audio_channels = _drflac->channels;
_audio_rate = _drflac->sampleRate;
@ -107,7 +130,7 @@ seek(double t) {
uint64_t sample = t * _drflac->sampleRate;
if (drflac_seek_to_sample(_drflac, sample * _drflac->channels)) {
if (drflac_seek_to_pcm_frame(_drflac, sample)) {
_last_seek = sample / (double)_drflac->sampleRate;
_samples_read = 0;
}
@ -120,8 +143,7 @@ seek(double t) {
*/
int FlacAudioCursor::
read_samples(int n, int16_t *data) {
int desired = n * _audio_channels;
n = drflac_read_s16(_drflac, desired, data) / _audio_channels;
n = (int)drflac_read_pcm_frames_s16(_drflac, n, data);
_samples_read += n;
return n;
}