add soft-clipping of mixed sounds using tanh

expose ADSR to TinyAudio API
enable envelope when playing wav files
This commit is contained in:
Erwin Coumans 2017-04-28 12:39:51 -07:00
parent 821ad96549
commit c95a1c9c33
8 changed files with 51 additions and 19 deletions

View File

@ -80,7 +80,7 @@ public:
virtual void initPhysics()
{
int numSoundSources = 8;
int numSoundSources = 32;
bool useRealTimeDac = true;
m_soundEngine.init(numSoundSources, useRealTimeDac);
@ -138,10 +138,13 @@ public:
b3SoundMessage msg;
msg.m_type = B3_SOUND_SOURCE_SINE_OSCILLATOR;
msg.m_frequency = freq;
msg.m_amplitude = .25;
msg.m_amplitude = 1;
//msg.m_type = B3_SOUND_SOURCE_WAV_FILE;
//msg.m_wavId = m_wavId;
msg.m_type = B3_SOUND_SOURCE_WAV_FILE;
msg.m_wavId = m_wavId;
msg.m_attackRate = 1;
msg.m_sustainLevel = 1;
msg.m_releaseRate = 0.001;
m_soundEngine.startSound(soundSourceIndex, msg);
m_keyToSoundSource.insert(hs,soundSourceIndex);

View File

@ -18,7 +18,7 @@ b3ADSR::b3ADSR()
{
m_target = 0.0;
m_value = 0.0;
m_attackRate = 0.0001;
m_attackRate = 0.001;
m_decayRate = 0.00001;
m_releaseRate = 0.0005;
m_sustainLevel = 0.5;

View File

@ -21,6 +21,15 @@ public:
bool isIdle() const;
void keyOn();
void keyOff();
void setValues(double attack,double decay,double sustain,double release)
{
m_attackRate = attack;
m_decayRate = decay;
m_sustainLevel = sustain;
m_releaseRate = release;
}
};
#endif //B3_ADSR_H

View File

@ -138,13 +138,9 @@ int b3AudioListener::tick(void *outputBuffer,void *inputBuffer1,unsigned int nBu
}
}
//simple mixer
if (numActiveSources)
{
outs[0] *= 1./4.;
outs[1] *= 1./4.;
}
//soft-clipping of sounds
outs[0] = tanh(outs[0]);
outs[1] = tanh(outs[1]);
*samples++ = outs[0];
*samples++ = outs[1];

View File

@ -101,14 +101,18 @@ int b3SoundEngine::getAvailableSoundSource()
void b3SoundEngine::startSound(int soundSourceIndex, b3SoundMessage msg)
{
b3SoundSource* soundSource = m_data->m_soundSources[soundSourceIndex];
soundSource->setOscillatorAmplitude(0,msg.m_amplitude);
soundSource->setOscillatorAmplitude(1,msg.m_amplitude);
soundSource->setADSR(msg.m_attackRate,msg.m_decayRate,msg.m_sustainLevel,msg.m_releaseRate);
switch (msg.m_type)
{
case B3_SOUND_SOURCE_SINE_OSCILLATOR:
{
soundSource->setOscillatorFrequency(0, msg.m_frequency);
soundSource->setOscillatorFrequency(1, msg.m_frequency);
soundSource->setOscillatorAmplitude(0,msg.m_amplitude);
soundSource->setOscillatorAmplitude(1,msg.m_amplitude);
soundSource->startSound();
break;
}

View File

@ -2,6 +2,7 @@
#define B3_SOUND_ENGINE_H
#include "Bullet3Common/b3Scalar.h"
#include "b3Sound_C_Api.h"
struct b3SoundMessage
{
@ -11,10 +12,22 @@ struct b3SoundMessage
double m_frequency;
int m_wavId;
double m_attack;
double m_decay;
double m_sustain;
double m_release;
double m_attackRate;
double m_decayRate;
double m_sustainLevel;
double m_releaseRate;
b3SoundMessage()
:m_type(B3_SOUND_SOURCE_SINE_OSCILLATOR),
m_amplitude(0.5),
m_frequency(440),
m_wavId(-1),
m_attackRate(0.001),
m_decayRate(0.00001),
m_sustainLevel(0.5),
m_releaseRate(0.0005)
{
}
};
class b3SoundEngine

View File

@ -80,6 +80,12 @@ b3SoundSource::~b3SoundSource()
delete m_data;
}
void b3SoundSource::setADSR( double attack, double decay, double sustain, double release)
{
m_data->m_envelope.setValues(attack,decay,sustain,release);
}
bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double sampleRate)
{
@ -110,7 +116,7 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double
if (m_data->m_oscillators[osc].m_type == 128)
{
int frame = 0;
double data = m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFilePtr->tick(frame,&m_data->m_oscillators[osc].m_wavTicker);
double data = env * m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFilePtr->tick(frame,&m_data->m_oscillators[osc].m_wavTicker);
samples[osc] += data;
numActive++;
}

View File

@ -20,6 +20,7 @@ public:
void setOscillatorFrequency(int oscillatorIndex, double frequency);
void setOscillatorAmplitude(int oscillatorIndex, double amplitude);
void setOscillatorPhase(int oscillatorIndex, double phase);
void setADSR( double attackRate, double decayRate, double sustainLevel, double releaseRate);
bool setWavFile(int oscillatorIndex, class b3ReadWavFile* wavFilePtr, int sampleRate);