Added "force mono" option to Music and SoundBuffer
Former-commit-id: 1f46d1461a8289a590a71e368f282a955d7d8234
This commit is contained in:
parent
faed82426f
commit
d902eea49e
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (C) 2013 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Audio module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_ALGORITHM_AUDIO_HPP
|
||||||
|
#define NAZARA_ALGORITHM_AUDIO_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
|
||||||
|
template<typename T> void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount);
|
||||||
|
|
||||||
|
#include <Nazara/Audio/Algorithm.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_ALGORITHM_AUDIO_HPP
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (C) 2013 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Audio module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Audio/Debug.hpp>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
|
||||||
|
{
|
||||||
|
// Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants
|
||||||
|
typedef typename std::conditional<std::is_unsigned<T>::value, nzUInt64, nzInt64>::type BiggestInt;
|
||||||
|
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < frameCount; ++i)
|
||||||
|
{
|
||||||
|
Biggest acc = Biggest(0);
|
||||||
|
for (unsigned int j = 0; j < channelCount; ++j)
|
||||||
|
acc += input[i*channelCount + j];
|
||||||
|
|
||||||
|
output[i] = acc/channelCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Audio/DebugOff.hpp>
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
struct NzMusicParams
|
struct NzMusicParams
|
||||||
{
|
{
|
||||||
|
bool forceMono = false;
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
struct NzSoundBufferParams
|
struct NzSoundBufferParams
|
||||||
{
|
{
|
||||||
|
bool forceMono = false;
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Audio/Loaders/sndfile.hpp>
|
#include <Nazara/Audio/Loaders/sndfile.hpp>
|
||||||
|
#include <Nazara/Audio/Algorithm.hpp>
|
||||||
#include <Nazara/Audio/Audio.hpp>
|
#include <Nazara/Audio/Audio.hpp>
|
||||||
#include <Nazara/Audio/Config.hpp>
|
#include <Nazara/Audio/Config.hpp>
|
||||||
#include <Nazara/Audio/Music.hpp>
|
#include <Nazara/Audio/Music.hpp>
|
||||||
|
|
@ -89,7 +90,10 @@ namespace
|
||||||
|
|
||||||
nzAudioFormat GetFormat() const
|
nzAudioFormat GetFormat() const
|
||||||
{
|
{
|
||||||
return m_format;
|
if (m_mixToMono)
|
||||||
|
return nzAudioFormat_Mono;
|
||||||
|
else
|
||||||
|
return m_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetSampleCount() const
|
unsigned int GetSampleCount() const
|
||||||
|
|
@ -102,7 +106,7 @@ namespace
|
||||||
return m_sampleRate;
|
return m_sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Open(const NzString& filePath)
|
bool Open(const NzString& filePath, bool forceMono)
|
||||||
{
|
{
|
||||||
m_file = new NzFile(filePath);
|
m_file = new NzFile(filePath);
|
||||||
if (!m_file->Open(NzFile::ReadOnly))
|
if (!m_file->Open(NzFile::ReadOnly))
|
||||||
|
|
@ -111,12 +115,14 @@ namespace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Open(*m_file);
|
return Open(*m_file, forceMono);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Open(NzInputStream& stream)
|
bool Open(NzInputStream& stream, bool forceMono)
|
||||||
{
|
{
|
||||||
SF_INFO infos;
|
SF_INFO infos;
|
||||||
|
infos.format = 0;
|
||||||
|
|
||||||
m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
|
m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
|
||||||
if (!m_handle)
|
if (!m_handle)
|
||||||
{
|
{
|
||||||
|
|
@ -127,10 +133,10 @@ namespace
|
||||||
m_format = NzAudio::GetAudioFormat(infos.channels);
|
m_format = NzAudio::GetAudioFormat(infos.channels);
|
||||||
if (m_format == nzAudioFormat_Unknown)
|
if (m_format == nzAudioFormat_Unknown)
|
||||||
{
|
{
|
||||||
NazaraError("Channel count not handled");
|
|
||||||
sf_close(m_handle);
|
sf_close(m_handle);
|
||||||
m_handle = nullptr;
|
m_handle = nullptr;
|
||||||
|
|
||||||
|
NazaraError("Channel count not handled");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,12 +151,29 @@ namespace
|
||||||
if (infos.format & SF_FORMAT_VORBIS)
|
if (infos.format & SF_FORMAT_VORBIS)
|
||||||
sf_command(m_handle, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);
|
sf_command(m_handle, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);
|
||||||
|
|
||||||
|
if (forceMono && m_format != nzAudioFormat_Mono)
|
||||||
|
{
|
||||||
|
m_mixToMono = true;
|
||||||
|
m_sampleCount = infos.frames;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_mixToMono = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Read(void* buffer, unsigned int sampleCount)
|
unsigned int Read(void* buffer, unsigned int sampleCount)
|
||||||
{
|
{
|
||||||
return sf_read_short(m_handle, reinterpret_cast<nzInt16*>(buffer), sampleCount);
|
if (m_mixToMono)
|
||||||
|
{
|
||||||
|
std::unique_ptr<nzInt16[]> samples(new nzInt16[m_format*sampleCount]);
|
||||||
|
unsigned int readSampleCount = sf_read_short(m_handle, samples.get(), m_format*sampleCount);
|
||||||
|
NzMixToMono(samples.get(), reinterpret_cast<nzInt16*>(buffer), m_format, sampleCount);
|
||||||
|
|
||||||
|
return readSampleCount / m_format;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return sf_read_short(m_handle, reinterpret_cast<nzInt16*>(buffer), sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Seek(nzUInt32 offset)
|
void Seek(nzUInt32 offset)
|
||||||
|
|
@ -162,6 +185,7 @@ namespace
|
||||||
nzAudioFormat m_format;
|
nzAudioFormat m_format;
|
||||||
NzFile* m_file;
|
NzFile* m_file;
|
||||||
SNDFILE* m_handle;
|
SNDFILE* m_handle;
|
||||||
|
bool m_mixToMono;
|
||||||
unsigned int m_duration;
|
unsigned int m_duration;
|
||||||
unsigned int m_sampleCount;
|
unsigned int m_sampleCount;
|
||||||
unsigned int m_sampleRate;
|
unsigned int m_sampleRate;
|
||||||
|
|
@ -199,7 +223,7 @@ namespace
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
||||||
if (!musicStream->Open(filePath))
|
if (!musicStream->Open(filePath, parameters.forceMono))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open music stream");
|
NazaraError("Failed to open music stream");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -221,7 +245,7 @@ namespace
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
||||||
if (!musicStream->Open(stream))
|
if (!musicStream->Open(stream, parameters.forceMono))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open music stream");
|
NazaraError("Failed to open music stream");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -295,6 +319,16 @@ namespace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameters.forceMono && format != nzAudioFormat_Mono)
|
||||||
|
{
|
||||||
|
std::unique_ptr<nzInt16[]> monoSamples(new nzInt16[info.frames]);
|
||||||
|
NzMixToMono(samples.get(), monoSamples.get(), info.channels, info.frames);
|
||||||
|
|
||||||
|
format = nzAudioFormat_Mono;
|
||||||
|
samples = std::move(monoSamples);
|
||||||
|
sampleCount = info.frames;
|
||||||
|
}
|
||||||
|
|
||||||
if (!soundBuffer->Create(format, static_cast<unsigned int>(sampleCount), info.samplerate, samples.get()))
|
if (!soundBuffer->Create(format, static_cast<unsigned int>(sampleCount), info.samplerate, samples.get()))
|
||||||
{
|
{
|
||||||
sf_close(file);
|
sf_close(file);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue