Exemplo n.º 1
0
AudioData LoadSoundCodec(std::string filename)
{

	std::string ext = FS::Path::Extension(filename);

	// if filename has extension, try to load it
	if (ext != "") {
		// look for the correct loader and use it
		for (int i = 0; i < numSoundLoaders; i++) {
			if (ext == soundLoaders[i].ext) {
				// if file exists, load it
				if (FS::PakPath::FileExists(filename)) {
					return soundLoaders[i].SoundLoader(filename);
				}
			}
		}
	}

	// if filename does not have extension or there is no file with such extension
	// or if there is no codec available for this file format,
	// try and find a suitable match using all the sound file formats supported
	// prioritize with the pak priority
	int bestLoader = -1;
	const FS::PakInfo* bestPak = nullptr;
	std::string strippedname = FS::Path::StripExtension(filename);

	for (int i = 0; i < numSoundLoaders; i++)
	{
		std::string altName = Str::Format("%s%s", strippedname, soundLoaders[i].ext);
		const FS::PakInfo* pak = FS::PakPath::LocateFile(altName);

		// We found a file and its pak is better than the best pak we have
		// this relies on how the filesystem works internally and should be moved
		// to a more explicit interface once there is one. (FIXME)
		if (pak != nullptr && (bestPak == nullptr || pak < bestPak ))
		{
			bestPak = pak;
			bestLoader = i;
		}
	}

	if (bestLoader >= 0)
	{
		std::string altName = Str::Format("%s%s", strippedname, soundLoaders[bestLoader].ext );
		return soundLoaders[bestLoader].SoundLoader(altName);
	}

	if (FS::PakPath::FileExists(filename)) {
		audioLogs.Warn("No codec available for opening %s.", filename);
		return AudioData();
	}

	audioLogs.Debug("Sound file %s not found.", filename);
	return AudioData();

}
Exemplo n.º 2
0
AudioData LoadOggCodec(std::string filename)
{
	std::string audioFile;
	try
	{
		audioFile = FS::PakPath::ReadFile(filename);
	}
	catch (std::system_error& err)
	{
		audioLogs.Warn("Failed to open %s: %s", filename, err.what());
		return AudioData();
	}
	OggDataSource dataSource = {&audioFile, 0};
	std::unique_ptr<OggVorbis_File> vorbisFile(new OggVorbis_File);

	if (ov_open_callbacks(&dataSource, vorbisFile.get(), nullptr, 0, Ogg_Callbacks) != 0) {
        audioLogs.Warn("Error while reading %s", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	if (ov_streams(vorbisFile.get()) != 1) {
		audioLogs.Warn("Unsupported number of streams in %s.", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	vorbis_info* oggInfo = ov_info(vorbisFile.get(), 0);

	if (!oggInfo) {
        audioLogs.Warn("Could not read vorbis_info in %s.", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	const int sampleWidth = 2;

	int sampleRate = oggInfo->rate;
	int numberOfChannels = oggInfo->channels;

	char buffer[4096];
	int bytesRead = 0;
	int bitStream = 0;

	std::vector<char> samples;

	while ((bytesRead = ov_read(vorbisFile.get(), buffer, 4096, 0, sampleWidth, 1, &bitStream)) > 0) {
		std::copy_n(buffer, bytesRead, std::back_inserter(samples));
	}
	ov_clear(vorbisFile.get());

	char* rawSamples = new char[samples.size()];
	std::copy_n(samples.data(), samples.size(), rawSamples);
	return AudioData(sampleRate, sampleWidth, numberOfChannels, samples.size(), rawSamples);
}
Exemplo n.º 3
0
AudioData LoadOpusCodec(std::string filename)
{
	std::string audioFile;
	try
	{
		audioFile = FS::PakPath::ReadFile(filename);
	}
	catch (std::system_error& err)
	{
		audioLogs.Warn("Failed to open %s: %s", filename, err.what());
		return AudioData();
	}

	OpusDataSource dataSource = {&audioFile, 0};
	OggOpusFile* opusFile = op_open_callbacks(&dataSource, &Opus_Callbacks, nullptr, 0, nullptr);

	if (!opusFile) {
		audioLogs.Warn("Error while reading %s", filename);
		return AudioData();
	}

	const OpusHead* opusInfo = op_head(opusFile, -1);

	if (!opusInfo) {
		op_free(opusFile);
		audioLogs.Warn("Could not read OpusHead in %s", filename);
		return AudioData();
	}

	if (opusInfo->stream_count != 1) {
		op_free(opusFile);
		audioLogs.Warn("Only one stream is supported in Opus files: %s", filename);
		return AudioData();
	}

	if (opusInfo->channel_count != 1 && opusInfo->channel_count != 2) {
		op_free(opusFile);
		audioLogs.Warn("Only mono and stereo Opus files are supported: %s", filename);
		return AudioData();
	}

	const int sampleWidth = 2;

	int sampleRate = 48000;
	int numberOfChannels = opusInfo->channel_count;

	// The buffer is big enough to hold 120ms worth of samples per channel
	opus_int16* buffer = new opus_int16[numberOfChannels * 5760];
	int samplesPerChannelRead = 0;

	std::vector<opus_int16> samples;

	while ((samplesPerChannelRead =
	            op_read(opusFile, buffer, sampleWidth * numberOfChannels * 5760, nullptr)) > 0) {
		std::copy_n(buffer, samplesPerChannelRead * numberOfChannels, std::back_inserter(samples));
	}

	op_free(opusFile);

	char* rawSamples = new char[sampleWidth * samples.size()];
	std::copy_n(reinterpret_cast<char*>(samples.data()), sampleWidth * samples.size(), rawSamples);

	return AudioData(sampleRate, sampleWidth, numberOfChannels, samples.size() * sampleWidth,
	                 rawSamples);
}
Exemplo n.º 4
0
AudioData LoadWavCodec(std::string filename)
{
	std::string audioFile;

	try
	{
		audioFile = std::move(FS::PakPath::ReadFile(filename));
	}
	catch (std::system_error& err)
	{
		audioLogs.Warn("Failed to open %s: %s", filename, err.what());
        return AudioData();
	}

	std::string format = audioFile.substr(8, 4);

	if (format != "WAVE") {
		audioLogs.Warn("The format label in %s is not \"WAVE\".", filename);
		return AudioData();
	}

	std::string chunk1ID = audioFile.substr(12, 4);

	if (chunk1ID != "fmt ") {
		audioLogs.Warn("The Chunk1ID in %s is not \"fmt\".", filename);
		return AudioData();
	}

	int numChannels = PackChars(audioFile, 22, 2);

	if (numChannels != 1 && numChannels != 2) {
		audioLogs.Warn("%s has an unsupported number of channels.", filename);
		return AudioData();
	}

	int sampleRate = PackChars(audioFile, 24, 4);
	int byteDepth = PackChars(audioFile, 34, 2) / 8;

	if (byteDepth != 1 && byteDepth != 2) {
		audioLogs.Warn("%s has an unsupported bytedepth.", filename);
		return AudioData();
	}

    //TODO  find the position of "data"
    std::size_t dataOffset{audioFile.find("data", 36)};
	if (dataOffset == std::string::npos) {
		audioLogs.Warn("Could not find the data chunk in %s", filename);
		return AudioData();
	}
	std::string chunk2ID = audioFile.substr(dataOffset, 4);

	int size = PackChars(audioFile, dataOffset + 4, 4);

	if (size <= 0 || sampleRate  <=0 ){
		audioLogs.Warn("Error in reading %s.", filename);
		return AudioData();
	}

	char* data = new char[size];

	std::copy_n(audioFile.data() + dataOffset + 8, size, data);

	return AudioData(sampleRate, byteDepth, numChannels, size, data);
}