From c95a1c9c339b92c3201271e5d04242608e50d329 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 28 Apr 2017 12:39:51 -0700 Subject: [PATCH] add soft-clipping of mixed sounds using tanh expose ADSR to TinyAudio API enable envelope when playing wav files --- examples/TinyAudio/TinyAudioExample.cpp | 11 +++++++---- examples/TinyAudio/b3ADSR.cpp | 2 +- examples/TinyAudio/b3ADSR.h | 9 +++++++++ examples/TinyAudio/b3AudioListener.cpp | 10 +++------- examples/TinyAudio/b3SoundEngine.cpp | 8 ++++++-- examples/TinyAudio/b3SoundEngine.h | 21 +++++++++++++++++---- examples/TinyAudio/b3SoundSource.cpp | 8 +++++++- examples/TinyAudio/b3SoundSource.h | 1 + 8 files changed, 51 insertions(+), 19 deletions(-) diff --git a/examples/TinyAudio/TinyAudioExample.cpp b/examples/TinyAudio/TinyAudioExample.cpp index 9fb17970f..43796de37 100644 --- a/examples/TinyAudio/TinyAudioExample.cpp +++ b/examples/TinyAudio/TinyAudioExample.cpp @@ -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); diff --git a/examples/TinyAudio/b3ADSR.cpp b/examples/TinyAudio/b3ADSR.cpp index 4f5b09b14..c1d1c9600 100644 --- a/examples/TinyAudio/b3ADSR.cpp +++ b/examples/TinyAudio/b3ADSR.cpp @@ -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; diff --git a/examples/TinyAudio/b3ADSR.h b/examples/TinyAudio/b3ADSR.h index 374ec409c..3523a7e86 100644 --- a/examples/TinyAudio/b3ADSR.h +++ b/examples/TinyAudio/b3ADSR.h @@ -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 \ No newline at end of file diff --git a/examples/TinyAudio/b3AudioListener.cpp b/examples/TinyAudio/b3AudioListener.cpp index dc78777c9..206df87fa 100644 --- a/examples/TinyAudio/b3AudioListener.cpp +++ b/examples/TinyAudio/b3AudioListener.cpp @@ -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]; diff --git a/examples/TinyAudio/b3SoundEngine.cpp b/examples/TinyAudio/b3SoundEngine.cpp index 851010a70..47f0ef4d9 100644 --- a/examples/TinyAudio/b3SoundEngine.cpp +++ b/examples/TinyAudio/b3SoundEngine.cpp @@ -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; } diff --git a/examples/TinyAudio/b3SoundEngine.h b/examples/TinyAudio/b3SoundEngine.h index 850a74ca5..9fe08ec00 100644 --- a/examples/TinyAudio/b3SoundEngine.h +++ b/examples/TinyAudio/b3SoundEngine.h @@ -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 diff --git a/examples/TinyAudio/b3SoundSource.cpp b/examples/TinyAudio/b3SoundSource.cpp index 527f28137..d7a2b4913 100644 --- a/examples/TinyAudio/b3SoundSource.cpp +++ b/examples/TinyAudio/b3SoundSource.cpp @@ -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++; } diff --git a/examples/TinyAudio/b3SoundSource.h b/examples/TinyAudio/b3SoundSource.h index fc6080ecc..a532eed37 100644 --- a/examples/TinyAudio/b3SoundSource.h +++ b/examples/TinyAudio/b3SoundSource.h @@ -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);