From 7754ca36a46c5ab9947907a0023827b7261a1064 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 2 Dec 2012 21:09:59 +0100 Subject: [PATCH] Added Music loader Former-commit-id: b0f1415a9fbc84152fa716c58794228d38c0bc63 --- src/Nazara/Audio/Loaders/sndfile/Loader.cpp | 159 ++++++++++++++++---- 1 file changed, 130 insertions(+), 29 deletions(-) diff --git a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp index c925e6fa6..dccf2d6cc 100644 --- a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp +++ b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp @@ -4,7 +4,9 @@ #include #include +#include #include +#include #include #include #include @@ -15,6 +17,8 @@ namespace { + const char* supportedFormats = "aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve"; + sf_count_t GetSize(void* user_data) { NzInputStream* stream = static_cast(user_data); @@ -59,7 +63,90 @@ namespace static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell}; - bool NzLoader_sndfile_Check(NzInputStream& stream, const NzSoundBufferParams& parameters) + class sndfileStream : public NzSoundStream + { + public: + sndfileStream() = default; + + ~sndfileStream() + { + if (m_file) + sf_close(m_file); + } + + nzUInt32 GetDuration() const + { + return m_duration; + } + + nzAudioFormat GetFormat() const + { + return m_format; + } + + unsigned int GetSampleCount() const + { + return m_sampleCount; + } + + unsigned int GetSampleRate() const + { + return m_sampleRate; + } + + bool Open(NzInputStream& stream) + { + SF_INFO infos; + m_file = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream); + if (!m_file) + { + NazaraError("Failed to open sound: " + NzString(sf_strerror(m_file))); + return false; + } + + m_format = NzAudio::GetAudioFormat(infos.channels); + if (m_format == nzAudioFormat_Unknown) + { + NazaraError("Channel count not handled"); + sf_close(m_file); + m_file = nullptr; + + return false; + } + + m_sampleCount = infos.channels*infos.frames; + m_sampleRate = infos.samplerate; + + m_duration = 1000*m_sampleCount / (m_format*m_sampleRate); + + // https://github.com/LaurentGomila/SFML/issues/271 + // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ + ///FIXME: Seulement le Vorbis ? + /*if (infos.format & SF_FORMAT_VORBIS) + sf_command(m_file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);*/ + + return true; + } + + unsigned int Read(void* buffer, unsigned int sampleCount) + { + return sf_read_short(m_file, reinterpret_cast(buffer), sampleCount); + } + + void Seek(nzUInt32 offset) + { + sf_seek(m_file, offset*m_sampleRate / 1000, SEEK_SET); + } + + private: + nzAudioFormat m_format; + SNDFILE* m_file = nullptr; + unsigned int m_duration; + unsigned int m_sampleCount; + unsigned int m_sampleRate; + }; + + bool NzLoader_sndfile_Check_Music(NzInputStream& stream, const NzMusicParams& parameters) { NazaraUnused(parameters); @@ -74,51 +161,65 @@ namespace return false; } - bool NzLoader_sndfile_Load(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters) + bool NzLoader_sndfile_Load_Music(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters) { NazaraUnused(parameters); - SF_INFO infos; - SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream); - if (!file) + sndfileStream* musicStream = new sndfileStream; + if (!musicStream->Open(stream)) { - NazaraError("Failed to load sound file: " + NzString(sf_strerror(file))); + // L'erreur a déjà été signalée par la méthode + delete musicStream; + return false; } - nzAudioFormat format = NzAudio::GetAudioFormat(infos.channels); - if (format == nzAudioFormat_Unknown) + if (!music->Create(musicStream)) + { + NazaraError("Failed to create music"); + delete musicStream; + + return false; + } + + return true; + } + + bool NzLoader_sndfile_Check_SoundBuffer(NzInputStream& stream, const NzSoundBufferParams& parameters) + { + NazaraUnused(parameters); + + SF_INFO info; + SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); + if (file) { - NazaraError("Channel count not handled"); sf_close(file); - - return false; + return true; } + else + return false; + } - // https://github.com/LaurentGomila/SFML/issues/271 - // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ - ///FIXME: Seulement le Vorbis ? - if (infos.format & SF_FORMAT_VORBIS) - sf_command(file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE); + bool NzLoader_sndfile_Load_SoundBuffer(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters) + { + NazaraUnused(parameters); - unsigned int sampleCount = infos.frames*infos.channels; + sndfileStream musicStream; + if (!musicStream.Open(stream)) + return false; // L'erreur a déjà été envoyée par la méthode + + unsigned int sampleCount = musicStream.GetSampleCount(); nzInt16* samples = new nzInt16[sampleCount]; - if (sf_read_short(file, samples, sampleCount) != sampleCount) + if (musicStream.Read(samples, sampleCount) != sampleCount) { NazaraError("Failed to read samples"); - - delete[] samples; - sf_close(file); - return false; } - if (!soundBuffer->Create(format, infos.frames*infos.channels, infos.samplerate, samples)) + if (!soundBuffer->Create(musicStream.GetFormat(), sampleCount, musicStream.GetSampleRate(), samples)) { NazaraError("Failed to create sound buffer"); - delete[] samples; - sf_close(file); return false; } @@ -131,12 +232,12 @@ namespace void NzLoaders_sndfile_Register() { - NzSoundBufferLoader::RegisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve", - NzLoader_sndfile_Check, NzLoader_sndfile_Load); + NzMusicLoader::RegisterLoader(supportedFormats, NzLoader_sndfile_Check_Music, NzLoader_sndfile_Load_Music); + NzSoundBufferLoader::RegisterLoader(supportedFormats, NzLoader_sndfile_Check_SoundBuffer, NzLoader_sndfile_Load_SoundBuffer); } void NzLoaders_sndfile_Unregister() { - NzSoundBufferLoader::UnregisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve", - NzLoader_sndfile_Check, NzLoader_sndfile_Load); + NzMusicLoader::UnregisterLoader(supportedFormats, NzLoader_sndfile_Check_Music, NzLoader_sndfile_Load_Music); + NzSoundBufferLoader::UnregisterLoader(supportedFormats, NzLoader_sndfile_Check_SoundBuffer, NzLoader_sndfile_Load_SoundBuffer); }