Add option to specify loop start in bgm tag

This commit is contained in:
mkwong98 2020-11-15 01:59:13 +08:00
parent 81b9ee5f72
commit 37e1b8dfec
7 changed files with 20 additions and 8 deletions

View file

@ -41,8 +41,9 @@ bool HdAudioDevice::PlayBgmTrack(uint8_t track, uint32_t startOffset)
{ {
int trackId = _album * 256 + track; int trackId = _album * 256 + track;
auto result = _hdData->BgmFilesById.find(trackId); auto result = _hdData->BgmFilesById.find(trackId);
auto result2 = _hdData->BgmLoopPointsById.find(trackId);
if(result != _hdData->BgmFilesById.end()) { if(result != _hdData->BgmFilesById.end()) {
if(_oggMixer->Play(result->second, false, startOffset)) { if(_oggMixer->Play(result->second, false, startOffset, result2->second)) {
_lastBgmTrack = trackId; _lastBgmTrack = trackId;
return true; return true;
} }
@ -56,7 +57,7 @@ bool HdAudioDevice::PlaySfx(uint8_t sfxNumber)
{ {
auto result = _hdData->SfxFilesById.find(_album * 256 + sfxNumber); auto result = _hdData->SfxFilesById.find(_album * 256 + sfxNumber);
if(result != _hdData->SfxFilesById.end()) { if(result != _hdData->SfxFilesById.end()) {
return !_oggMixer->Play(result->second, true, 0); return !_oggMixer->Play(result->second, true, 0, 0);
} else { } else {
MessageManager::Log("[HDPack] Invalid album+sfx number combination: " + std::to_string(_album) + ":" + std::to_string(sfxNumber)); MessageManager::Log("[HDPack] Invalid album+sfx number combination: " + std::to_string(_album) + ":" + std::to_string(sfxNumber));
return false; return false;

View file

@ -356,6 +356,7 @@ struct HdPackData
std::unordered_map<HdTileKey, vector<HdPackTileInfo*>> TileByKey; std::unordered_map<HdTileKey, vector<HdPackTileInfo*>> TileByKey;
std::unordered_map<string, string> PatchesByHash; std::unordered_map<string, string> PatchesByHash;
std::unordered_map<int, string> BgmFilesById; std::unordered_map<int, string> BgmFilesById;
std::unordered_map<int, uint32_t> BgmLoopPointsById;
std::unordered_map<int, string> SfxFilesById; std::unordered_map<int, string> SfxFilesById;
vector<uint32_t> Palette; vector<uint32_t> Palette;

View file

@ -655,6 +655,12 @@ void HdPackLoader::ProcessBgmTag(vector<string> &tokens)
} else { } else {
_data->BgmFilesById[trackId] = FolderUtilities::CombinePath(_hdPackFolder, tokens[2]); _data->BgmFilesById[trackId] = FolderUtilities::CombinePath(_hdPackFolder, tokens[2]);
} }
if (tokens.size() >= 4) {
stringstream pt(tokens[3]);
uint32_t loopPoint;
pt >> loopPoint;
_data->BgmLoopPointsById[trackId] = loopPoint;
}
} }
} }

View file

@ -80,11 +80,11 @@ void OggMixer::SetSampleRate(int sampleRate)
} }
} }
bool OggMixer::Play(string filename, bool isSfx, uint32_t startOffset) bool OggMixer::Play(string filename, bool isSfx, uint32_t startOffset, uint32_t loopPoint)
{ {
shared_ptr<OggReader> reader(new OggReader()); shared_ptr<OggReader> reader(new OggReader());
bool loop = !isSfx && (_options & (int)OggPlaybackOptions::Loop) != 0; bool loop = !isSfx && (_options & (int)OggPlaybackOptions::Loop) != 0;
if(reader->Init(filename, loop, _sampleRate, startOffset)) { if(reader->Init(filename, loop, _sampleRate, startOffset, loopPoint)) {
if(isSfx) { if(isSfx) {
_sfx.push_back(reader); _sfx.push_back(reader);
} else { } else {

View file

@ -22,7 +22,7 @@ public:
void ApplySamples(int16_t* buffer, size_t sampleCount, double masterVolumne); void ApplySamples(int16_t* buffer, size_t sampleCount, double masterVolumne);
void Reset(uint32_t sampleRate); void Reset(uint32_t sampleRate);
bool Play(string filename, bool isSfx, uint32_t startOffset); bool Play(string filename, bool isSfx, uint32_t startOffset, uint32_t loopPoint);
void SetPlaybackOptions(uint8_t options); void SetPlaybackOptions(uint8_t options);
void SetPausedFlag(bool paused); void SetPausedFlag(bool paused);
void StopBgm(); void StopBgm();

View file

@ -22,21 +22,24 @@ OggReader::~OggReader()
} }
} }
bool OggReader::Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset) bool OggReader::Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset, uint32_t loopPoint)
{ {
int error; int error;
VirtualFile file = filename; VirtualFile file = filename;
_fileData = vector<uint8_t>(100000); _fileData = vector<uint8_t>(100000);
if(file.ReadFile(_fileData)) { if(file.ReadFile(_fileData)) {
_vorbis = stb_vorbis_open_memory(_fileData.data(), (int)_fileData.size(), &error, nullptr); _vorbis = stb_vorbis_open_memory(_fileData.data(), (int)_fileData.size(), &error, nullptr);
if(_vorbis) { if(_vorbis) {
_loop = loop; _loop = loop;
_loopPoint = loopPoint;
_oggSampleRate = stb_vorbis_get_info(_vorbis).sample_rate; _oggSampleRate = stb_vorbis_get_info(_vorbis).sample_rate;
if(startOffset > 0) { if(startOffset > 0) {
stb_vorbis_seek(_vorbis, startOffset); stb_vorbis_seek(_vorbis, startOffset);
} }
blip_set_rates(_blipLeft, _oggSampleRate, sampleRate); blip_set_rates(_blipLeft, _oggSampleRate, sampleRate);
blip_set_rates(_blipRight, _oggSampleRate, sampleRate); blip_set_rates(_blipRight, _oggSampleRate, sampleRate);
return true; return true;
} }
} }
@ -78,7 +81,7 @@ bool OggReader::LoadSamples()
if(samplesReturned < OggReader::SamplesToRead) { if(samplesReturned < OggReader::SamplesToRead) {
if(_loop) { if(_loop) {
stb_vorbis_seek_start(_vorbis); stb_vorbis_seek(_vorbis, _loopPoint);
LoadSamples(); LoadSamples();
} else { } else {
_done = true; _done = true;

View file

@ -15,6 +15,7 @@ private:
bool _loop; bool _loop;
bool _done; bool _done;
uint32_t _loopPoint;
blip_t* _blipLeft; blip_t* _blipLeft;
blip_t* _blipRight; blip_t* _blipRight;
@ -30,7 +31,7 @@ public:
OggReader(); OggReader();
~OggReader(); ~OggReader();
bool Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset = 0); bool Init(string filename, bool loop, uint32_t sampleRate, uint32_t startOffset = 0, uint32_t loopPoint = 0);
bool IsPlaybackOver(); bool IsPlaybackOver();
void SetSampleRate(int sampleRate); void SetSampleRate(int sampleRate);
void SetLoopFlag(bool loop); void SetLoopFlag(bool loop);