mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-24 09:09:44 +00:00
Load sound loudness and store it with the Sound_Buffer
Still not used for say yet, though
This commit is contained in:
parent
f4c22ec49e
commit
495e138907
9 changed files with 91 additions and 89 deletions
|
@ -8,14 +8,15 @@
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
|
||||||
void analyzeLoudness(const std::vector<char> &data, int sampleRate, ChannelConfig chans,
|
void Sound_Loudness::analyzeLoudness(const std::vector< char >& data, int sampleRate, ChannelConfig chans, SampleType type, float valuesPerSecond)
|
||||||
SampleType type, std::vector<float> &out, float valuesPerSecond)
|
{
|
||||||
{
|
|
||||||
int samplesPerSegment = static_cast<int>(sampleRate / valuesPerSecond);
|
int samplesPerSegment = static_cast<int>(sampleRate / valuesPerSecond);
|
||||||
int numSamples = bytesToFrames(data.size(), chans, type);
|
int numSamples = bytesToFrames(data.size(), chans, type);
|
||||||
int advance = framesToBytes(1, chans, type);
|
int advance = framesToBytes(1, chans, type);
|
||||||
|
|
||||||
out.reserve(numSamples/samplesPerSegment);
|
mSamplesPerSec = valuesPerSecond;
|
||||||
|
mSamples.clear();
|
||||||
|
mSamples.reserve(numSamples/samplesPerSegment);
|
||||||
|
|
||||||
int segment=0;
|
int segment=0;
|
||||||
int sample=0;
|
int sample=0;
|
||||||
|
@ -48,9 +49,20 @@ namespace MWSound
|
||||||
float rms = 0; // root mean square
|
float rms = 0; // root mean square
|
||||||
if (samplesAdded > 0)
|
if (samplesAdded > 0)
|
||||||
rms = std::sqrt(sum / samplesAdded);
|
rms = std::sqrt(sum / samplesAdded);
|
||||||
out.push_back(rms);
|
mSamples.push_back(rms);
|
||||||
++segment;
|
++segment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Sound_Loudness::getLoudnessAtTime(float sec) const
|
||||||
|
{
|
||||||
|
if(mSamplesPerSec <= 0.0f || mSamples.empty() || sec < 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
size_t index = static_cast<size_t>(sec * mSamplesPerSec);
|
||||||
|
index = std::max<size_t>(0, std::min(index, mSamples.size()-1));
|
||||||
|
return mSamples[index];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
|
#ifndef GAME_SOUND_LOUDNESS_H
|
||||||
|
#define GAME_SOUND_LOUDNESS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "sound_decoder.hpp"
|
#include "sound_decoder.hpp"
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
class Sound_Loudness {
|
||||||
|
// Loudness sample info
|
||||||
|
float mSamplesPerSec;
|
||||||
|
std::vector<float> mSamples;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Sound_Loudness() : mSamplesPerSec(0.0f) { }
|
||||||
|
|
||||||
|
/**
|
||||||
* Analyzes the energy (closely related to loudness) of a sound buffer.
|
* Analyzes the energy (closely related to loudness) of a sound buffer.
|
||||||
* The buffer will be divided into segments according to \a valuesPerSecond,
|
* The buffer will be divided into segments according to \a valuesPerSecond,
|
||||||
* and for each segment a loudness value in the range of [0,1] will be computed.
|
* and for each segment a loudness value in the range of [0,1] will be computed.
|
||||||
|
@ -11,10 +24,15 @@ namespace MWSound
|
||||||
* @param sampleRate the sample rate of the sound buffer
|
* @param sampleRate the sample rate of the sound buffer
|
||||||
* @param chans channel layout of the buffer
|
* @param chans channel layout of the buffer
|
||||||
* @param type sample type of the buffer
|
* @param type sample type of the buffer
|
||||||
* @param out Will contain the output loudness values.
|
|
||||||
* @param valuesPerSecond How many loudness values per second of audio to compute.
|
* @param valuesPerSecond How many loudness values per second of audio to compute.
|
||||||
*/
|
*/
|
||||||
void analyzeLoudness (const std::vector<char>& data, int sampleRate, ChannelConfig chans, SampleType type,
|
void analyzeLoudness(const std::vector<char>& data, int sampleRate,
|
||||||
std::vector<float>& out, float valuesPerSecond);
|
ChannelConfig chans, SampleType type,
|
||||||
|
float valuesPerSecond);
|
||||||
|
|
||||||
|
float getLoudnessAtTime(float sec) const;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* GAME_SOUND_LOUDNESS_H */
|
||||||
|
|
|
@ -751,7 +751,7 @@ void OpenAL_Output::deinit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
|
Sound_Handle OpenAL_Output::loadSound(const std::string &fname, Sound_Loudness *loudness)
|
||||||
{
|
{
|
||||||
throwALerror();
|
throwALerror();
|
||||||
|
|
||||||
|
@ -778,7 +778,8 @@ Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
|
||||||
decoder->readAll(data);
|
decoder->readAll(data);
|
||||||
decoder->close();
|
decoder->close();
|
||||||
|
|
||||||
//analyzeLoudness(data, srate, chans, type, cached.mLoudnessVector, static_cast<float>(loudnessFPS));
|
if(loudness != 0)
|
||||||
|
loudness->analyzeLoudness(data, srate, chans, type, static_cast<float>(loudnessFPS));
|
||||||
|
|
||||||
ALuint buf = 0;
|
ALuint buf = 0;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace MWSound
|
||||||
virtual void init(const std::string &devname="");
|
virtual void init(const std::string &devname="");
|
||||||
virtual void deinit();
|
virtual void deinit();
|
||||||
|
|
||||||
virtual Sound_Handle loadSound(const std::string &fname);
|
virtual Sound_Handle loadSound(const std::string &fname, Sound_Loudness *loudness);
|
||||||
virtual void unloadSound(Sound_Handle data);
|
virtual void unloadSound(Sound_Handle data);
|
||||||
|
|
||||||
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#include "sound.hpp"
|
|
||||||
|
|
||||||
namespace MWSound
|
|
||||||
{
|
|
||||||
|
|
||||||
float Sound::getCurrentLoudness()
|
|
||||||
{
|
|
||||||
if (mLoudnessVector.empty())
|
|
||||||
return 0.f;
|
|
||||||
int index = static_cast<int>(getTimeOffset() * mLoudnessFPS);
|
|
||||||
|
|
||||||
index = std::max(0, std::min(index, int(mLoudnessVector.size()-1)));
|
|
||||||
|
|
||||||
return mLoudnessVector[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sound::setLoudnessVector(const std::vector<float> &loudnessVector, float loudnessFPS)
|
|
||||||
{
|
|
||||||
mLoudnessVector = loudnessVector;
|
|
||||||
mLoudnessFPS = loudnessFPS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -22,9 +22,6 @@ namespace MWSound
|
||||||
int mFlags;
|
int mFlags;
|
||||||
float mFadeOutTime;
|
float mFadeOutTime;
|
||||||
|
|
||||||
std::vector<float> mLoudnessVector;
|
|
||||||
float mLoudnessFPS;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
virtual bool isPlaying() = 0;
|
virtual bool isPlaying() = 0;
|
||||||
|
@ -32,11 +29,6 @@ namespace MWSound
|
||||||
void setPosition(const osg::Vec3f &pos) { mPos = pos; }
|
void setPosition(const osg::Vec3f &pos) { mPos = pos; }
|
||||||
void setVolume(float volume) { mVolume = volume; }
|
void setVolume(float volume) { mVolume = volume; }
|
||||||
void setFadeout(float duration) { mFadeOutTime=duration; }
|
void setFadeout(float duration) { mFadeOutTime=duration; }
|
||||||
void setLoudnessVector(const std::vector<float>& loudnessVector, float loudnessFPS);
|
|
||||||
|
|
||||||
/// Get loudness at the current time position on a [0,1] scale.
|
|
||||||
/// Requires that loudnessVector was filled in by the user.
|
|
||||||
float getCurrentLoudness();
|
|
||||||
|
|
||||||
MWBase::SoundManager::PlayType getPlayType() const
|
MWBase::SoundManager::PlayType getPlayType() const
|
||||||
{ return (MWBase::SoundManager::PlayType)(mFlags&MWBase::SoundManager::Play_TypeMask); }
|
{ return (MWBase::SoundManager::PlayType)(mFlags&MWBase::SoundManager::Play_TypeMask); }
|
||||||
|
@ -51,7 +43,6 @@ namespace MWSound
|
||||||
, mMaxDistance(maxdist)
|
, mMaxDistance(maxdist)
|
||||||
, mFlags(flags)
|
, mFlags(flags)
|
||||||
, mFadeOutTime(0)
|
, mFadeOutTime(0)
|
||||||
, mLoudnessFPS(20)
|
|
||||||
{ }
|
{ }
|
||||||
virtual ~Sound() { }
|
virtual ~Sound() { }
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "soundmanagerimp.hpp"
|
#include "soundmanagerimp.hpp"
|
||||||
#include "sound_output.hpp"
|
#include "sound_output.hpp"
|
||||||
|
#include "loudness.hpp"
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ namespace MWSound
|
||||||
float mMinDist, mMaxDist;
|
float mMinDist, mMaxDist;
|
||||||
|
|
||||||
Sound_Handle mHandle;
|
Sound_Handle mHandle;
|
||||||
|
Sound_Loudness mLoudness;
|
||||||
|
|
||||||
Sound_Buffer(std::string resname, float volume, float mindist, float maxdist)
|
Sound_Buffer(std::string resname, float volume, float mindist, float maxdist)
|
||||||
: mResourceName(resname), mVolume(volume), mMinDist(mindist), mMaxDist(maxdist), mHandle(0)
|
: mResourceName(resname), mVolume(volume), mMinDist(mindist), mMaxDist(maxdist), mHandle(0)
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace MWSound
|
||||||
class SoundManager;
|
class SoundManager;
|
||||||
struct Sound_Decoder;
|
struct Sound_Decoder;
|
||||||
class Sound;
|
class Sound;
|
||||||
|
class Sound_Loudness;
|
||||||
|
|
||||||
// An opaque handle for the implementation's sound buffers.
|
// An opaque handle for the implementation's sound buffers.
|
||||||
typedef void *Sound_Handle;
|
typedef void *Sound_Handle;
|
||||||
|
@ -25,7 +26,7 @@ namespace MWSound
|
||||||
virtual void init(const std::string &devname="") = 0;
|
virtual void init(const std::string &devname="") = 0;
|
||||||
virtual void deinit() = 0;
|
virtual void deinit() = 0;
|
||||||
|
|
||||||
virtual Sound_Handle loadSound(const std::string &fname) = 0;
|
virtual Sound_Handle loadSound(const std::string &fname, Sound_Loudness *loudness=0) = 0;
|
||||||
virtual void unloadSound(Sound_Handle data) = 0;
|
virtual void unloadSound(Sound_Handle data) = 0;
|
||||||
|
|
||||||
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
||||||
|
|
|
@ -189,10 +189,10 @@ namespace MWSound
|
||||||
voicefile, Sound_Buffer("sound/"+voicefile, 1.0f, minDistance, maxDistance)
|
voicefile, Sound_Buffer("sound/"+voicefile, 1.0f, minDistance, maxDistance)
|
||||||
)).first;
|
)).first;
|
||||||
mVFS->normalizeFilename(sfxiter->second.mResourceName);
|
mVFS->normalizeFilename(sfxiter->second.mResourceName);
|
||||||
sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName);
|
sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName, &sfxiter->second.mLoudness);
|
||||||
}
|
}
|
||||||
else if(!sfxiter->second.mHandle)
|
else if(!sfxiter->second.mHandle)
|
||||||
sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName);
|
sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName, &sfxiter->second.mLoudness);
|
||||||
|
|
||||||
return &sfxiter->second;
|
return &sfxiter->second;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ namespace MWSound
|
||||||
if (snditer == mActiveSounds.end())
|
if (snditer == mActiveSounds.end())
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
return snditer->first->getCurrentLoudness();
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::say(const std::string& filename)
|
void SoundManager::say(const std::string& filename)
|
||||||
|
|
Loading…
Reference in a new issue