1
0
Fork 0
OpenTTD/src/soundloader.cpp

74 lines
2.8 KiB
C++

/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file soundloader.cpp Handling of loading sounds. */
#include "stdafx.h"
#include "debug.h"
#include "sound_type.h"
#include "soundloader_type.h"
#include "soundloader_func.h"
#include "string_func.h"
#include "newgrf_sound.h"
#include "random_access_file_type.h"
#include "safeguards.h"
template class ProviderManager<SoundLoader>;
bool LoadSoundData(SoundEntry &sound, bool new_format, SoundID sound_id, const std::string &name)
{
/* Check for valid sound size. */
if (sound.file_size == 0 || sound.file_size > SIZE_MAX - 2) return false;
size_t pos = sound.file->GetPos();
sound.data = std::make_shared<std::vector<uint8_t>>();
for (auto &loader : ProviderManager<SoundLoader>::GetProviders()) {
sound.file->SeekTo(pos, SEEK_SET);
if (loader->Load(sound, new_format, *sound.data)) break;
}
if (sound.data->empty()) {
Debug(grf, 0, "LoadSound [{}]: Failed to load sound '{}' for slot {}", sound.file->GetSimplifiedFilename(), name, sound_id);
return false;
}
assert(sound.bits_per_sample == 8 || sound.bits_per_sample == 16);
assert(sound.channels == 1);
assert(sound.rate != 0);
Debug(grf, 2, "LoadSound [{}]: channels {}, sample rate {}, bits per sample {}, length {}", sound.file->GetSimplifiedFilename(), sound.channels, sound.rate, sound.bits_per_sample, sound.file_size);
/* Mixer always requires an extra sample at the end for the built-in linear resampler. */
sound.data->resize(sound.data->size() + sound.channels * sound.bits_per_sample / 8);
sound.data->shrink_to_fit();
return true;
}
static bool LoadBasesetSound(SoundEntry &sound, bool new_format, SoundID sound_id)
{
sound.file->SeekTo(sound.file_offset, SEEK_SET);
/* Read name of sound for diagnostics. */
size_t name_len = sound.file->ReadByte();
std::string name(name_len, '\0');
sound.file->ReadBlock(name.data(), name_len);
return LoadSoundData(sound, new_format, sound_id, StrMakeValid(name));
}
bool LoadSound(SoundEntry &sound, SoundID sound_id)
{
switch (sound.source) {
case SoundSource::BasesetOldFormat: return LoadBasesetSound(sound, false, sound_id);
case SoundSource::BasesetNewFormat: return LoadBasesetSound(sound, true, sound_id);
case SoundSource::NewGRF: return LoadNewGRFSound(sound, sound_id);
default: NOT_REACHED();
}
}