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
|
||||
{
|
||||
bool forceMono = false;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
struct NzSoundBufferParams
|
||||
{
|
||||
bool forceMono = false;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Audio/Loaders/sndfile.hpp>
|
||||
#include <Nazara/Audio/Algorithm.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Music.hpp>
|
||||
|
|
@ -89,7 +90,10 @@ namespace
|
|||
|
||||
nzAudioFormat GetFormat() const
|
||||
{
|
||||
return m_format;
|
||||
if (m_mixToMono)
|
||||
return nzAudioFormat_Mono;
|
||||
else
|
||||
return m_format;
|
||||
}
|
||||
|
||||
unsigned int GetSampleCount() const
|
||||
|
|
@ -102,7 +106,7 @@ namespace
|
|||
return m_sampleRate;
|
||||
}
|
||||
|
||||
bool Open(const NzString& filePath)
|
||||
bool Open(const NzString& filePath, bool forceMono)
|
||||
{
|
||||
m_file = new NzFile(filePath);
|
||||
if (!m_file->Open(NzFile::ReadOnly))
|
||||
|
|
@ -111,12 +115,14 @@ namespace
|
|||
return false;
|
||||
}
|
||||
|
||||
return Open(*m_file);
|
||||
return Open(*m_file, forceMono);
|
||||
}
|
||||
|
||||
bool Open(NzInputStream& stream)
|
||||
bool Open(NzInputStream& stream, bool forceMono)
|
||||
{
|
||||
SF_INFO infos;
|
||||
infos.format = 0;
|
||||
|
||||
m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
|
||||
if (!m_handle)
|
||||
{
|
||||
|
|
@ -127,10 +133,10 @@ namespace
|
|||
m_format = NzAudio::GetAudioFormat(infos.channels);
|
||||
if (m_format == nzAudioFormat_Unknown)
|
||||
{
|
||||
NazaraError("Channel count not handled");
|
||||
sf_close(m_handle);
|
||||
m_handle = nullptr;
|
||||
|
||||
NazaraError("Channel count not handled");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -145,12 +151,29 @@ namespace
|
|||
if (infos.format & SF_FORMAT_VORBIS)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -162,6 +185,7 @@ namespace
|
|||
nzAudioFormat m_format;
|
||||
NzFile* m_file;
|
||||
SNDFILE* m_handle;
|
||||
bool m_mixToMono;
|
||||
unsigned int m_duration;
|
||||
unsigned int m_sampleCount;
|
||||
unsigned int m_sampleRate;
|
||||
|
|
@ -199,7 +223,7 @@ namespace
|
|||
NazaraUnused(parameters);
|
||||
|
||||
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
||||
if (!musicStream->Open(filePath))
|
||||
if (!musicStream->Open(filePath, parameters.forceMono))
|
||||
{
|
||||
NazaraError("Failed to open music stream");
|
||||
return false;
|
||||
|
|
@ -221,7 +245,7 @@ namespace
|
|||
NazaraUnused(parameters);
|
||||
|
||||
std::unique_ptr<sndfileStream> musicStream(new sndfileStream);
|
||||
if (!musicStream->Open(stream))
|
||||
if (!musicStream->Open(stream, parameters.forceMono))
|
||||
{
|
||||
NazaraError("Failed to open music stream");
|
||||
return false;
|
||||
|
|
@ -295,6 +319,16 @@ namespace
|
|||
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()))
|
||||
{
|
||||
sf_close(file);
|
||||
|
|
|
|||
Loading…
Reference in New Issue