create basic audio, towards sound sensors etc.

This commit is contained in:
Erwin Coumans
2017-04-14 12:22:38 -07:00
parent fec96ab17f
commit eef76af663
11 changed files with 11788 additions and 2 deletions

View File

@@ -35,7 +35,7 @@ int main(int argc, char* argv[])
CommonExampleInterface* example = StandaloneExampleCreateFunc(options);
example->initPhysics();
for (int i = 0; i < 1000; i++)
for (int i = 0; i < 100000; i++)
{
printf("Simulating step %d\n", i);
example->stepSimulation(1.f / 60.f);

10228
examples/TinyAudio/RtAudio.cpp Normal file

File diff suppressed because it is too large Load Diff

1163
examples/TinyAudio/RtAudio.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
#include "TinyAudioExample.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "RtAudio.h"
#include "b3AudioListener.h"
#include "b3SoundSource.h"
class TinyAudioExample : public CommonExampleInterface
{
b3AudioListener m_listener;
b3SoundSource m_soundA;
RtAudio m_dac;
GUIHelperInterface* m_guiHelper;
int m_soundIndexA;
public:
TinyAudioExample(struct GUIHelperInterface* helper)
:m_guiHelper(helper)
{
}
virtual ~TinyAudioExample()
{
}
virtual void initPhysics()
{
m_soundIndexA = m_listener.addSoundSource(&m_soundA);
RtAudioFormat format = ( sizeof(double) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
RtAudio::StreamParameters parameters;
parameters.deviceId = 1;// dac.getDefaultOutputDevice();
parameters.nChannels = 2;
// The default real-time audio input and output buffer size. If
// clicks are occuring in the input and/or output sound stream, a
// larger buffer size may help. Larger buffer sizes, however, produce
// more latency.
const unsigned int RT_BUFFER_SIZE = 512;
unsigned int bufferFrames = RT_BUFFER_SIZE;
int sampleRate = m_listener.getSampleRate();
m_dac.openStream( &parameters, NULL, format, (unsigned int)sampleRate, &bufferFrames, &b3AudioListener::tick,
(void *)m_listener.getTickData());
// Install an interrupt handler function.
// (void) signal( SIGINT, finish );
m_dac.startStream();
}
virtual void exitPhysics()
{
m_dac.closeStream();
m_listener.removeSoundSource(m_soundIndexA);
}
virtual void renderScene()
{
}
virtual void stepSimulation(float deltaTime)
{
}
virtual void physicsDebugDraw(int debugFlags)
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
void resetCamera()
{
float dist = 4;
float pitch = 52;
float yaw = 35;
float targetPos[3]={0,0,0};
m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
}
};
CommonExampleInterface* TinyAudioExampleCreateFunc(CommonExampleOptions& options)
{
return new TinyAudioExample(options.m_guiHelper);
}
B3_STANDALONE_EXAMPLE(TinyAudioExampleCreateFunc)

View File

@@ -0,0 +1,7 @@
#ifndef TINY_AUDIO_EXAMPLE_H
#define TINY_AUDIO_EXAMPLE_H
class CommonExampleInterface* TinyAudioExampleCreateFunc(struct CommonExampleOptions& options);
#endif //TINY_AUDIO_EXAMPLE_H

View File

@@ -0,0 +1,132 @@
#include "b3AudioListener.h"
#include "b3SoundSource.h"
template <class T>
inline const T& MyMin(const T& a, const T& b)
{
return a < b ? a : b ;
}
#define MAX_SOUND_SOURCES 128
struct b3AudioListenerInternalData
{
int m_numControlTicks;
double m_sampleRate;
b3SoundSource* m_soundSources[MAX_SOUND_SOURCES];
b3AudioListenerInternalData()
:m_numControlTicks(64),
m_sampleRate(48000)
{
for (int i=0;i<MAX_SOUND_SOURCES;i++)
{
m_soundSources[i] = 0;
}
}
};
b3AudioListener::b3AudioListener()
{
m_data = new b3AudioListenerInternalData();
}
b3AudioListener::~b3AudioListener()
{
delete m_data;
}
int b3AudioListener::addSoundSource(b3SoundSource* source)
{
int soundIndex = -1;
for (int i=0;i<MAX_SOUND_SOURCES;i++)
{
if (m_data->m_soundSources[i]==0)
{
m_data->m_soundSources[i] = source;
soundIndex = i;
break;
}
}
return soundIndex;
}
void b3AudioListener::removeSoundSource(int soundSourceIndex)
{
if (soundSourceIndex >=0 && soundSourceIndex<MAX_SOUND_SOURCES)
{
m_data->m_soundSources[soundSourceIndex] = 0;
}
}
b3AudioListenerInternalData* b3AudioListener::getTickData()
{
return m_data;
}
const b3AudioListenerInternalData* b3AudioListener::getTickData() const
{
return m_data;
}
double b3AudioListener::getSampleRate() const
{
return m_data->m_sampleRate;
}
int b3AudioListener::tick(void *outputBuffer,void *inputBuffer1,unsigned int nBufferFrames,
double streamTime,unsigned int status,void *dataPointer)
{
b3AudioListenerInternalData *data = (b3AudioListenerInternalData *)dataPointer;
register double outs[2],*samples = (double *)outputBuffer;
register double tempOuts[2];
int counter,nTicks = (int)nBufferFrames;
bool done = false;
while(nTicks > 0 && !done)
{
counter = MyMin(nTicks,data->m_numControlTicks);
bool newsynth = true;
if(newsynth)
{
for(int i = 0; i < counter; i++)
{
outs[0] = 0.;
outs[1] = 0.;
//make_sound_double(outs,1);
float numActiveSources = 0;
for (int i=0;i<MAX_SOUND_SOURCES;i++)
{
if (data->m_soundSources[i])
{
if (data->m_soundSources[i]->computeSamples(tempOuts,1, data->m_sampleRate))
{
numActiveSources++;
//simple mixer
outs[0] += tempOuts[0];
outs[1] += tempOuts[1];
}
}
}
//simple mixer
if (numActiveSources)
{
outs[0] *= 1./numActiveSources;
outs[1] *= 1./numActiveSources;
}
*samples++ = outs[0];
*samples++ = outs[1];
}
nTicks -= counter;
}
if(nTicks == 0)
break;
}
return 0;
}

View File

@@ -0,0 +1,28 @@
#ifndef B3_AUDIO_LISTENER_H
#define B3_AUDIO_LISTENER_H
class b3SoundSource;
class b3AudioListener
{
struct b3AudioListenerInternalData* m_data;
public:
b3AudioListener();
virtual ~b3AudioListener();
static int tick(void *outputBuffer, void *inputBuffer1, unsigned int nBufferFrames,
double streamTime, unsigned int status, void *dataPointer);
int addSoundSource(b3SoundSource* source);
void removeSoundSource(int soundSourceIndex);
b3AudioListenerInternalData* getTickData();
const b3AudioListenerInternalData* getTickData() const;
double getSampleRate() const;
};
#endif //B3_AUDIO_LISTENER_H

View File

@@ -0,0 +1,66 @@
#include "b3SoundSource.h"
#define MY2PI (2.*3.14159265)
#include <math.h>
struct b3SoundOscillator
{
int m_type;
double m_amplitude;
double m_phase;
double m_frequency;
double sampleWaveForm(double sampleRate)
{
while (m_phase >= MY2PI)
m_phase -= MY2PI;
double z = sinf(m_phase);
double sample = m_amplitude*z;
m_phase += MY2PI * (1./sampleRate) * m_frequency;
return sample;
}
b3SoundOscillator()
:m_phase(0),
m_amplitude(0.8),
m_frequency(442.)
{
}
};
struct b3SoundSourceInternalData
{
b3SoundOscillator m_oscillator;
};
b3SoundSource::b3SoundSource()
{
m_data = new b3SoundSourceInternalData();
}
b3SoundSource::~b3SoundSource()
{
delete m_data;
}
bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double sampleRate)
{
double* outputSamples = sampleBuffer;
for (int i=0;i<numSamples;i++)
{
double sample = m_data->m_oscillator.sampleWaveForm(sampleRate);
double sampleLeft = sample;
double sampleRight = sample;
*outputSamples++ = sampleLeft;
*outputSamples++ = sampleRight;
}
return true;
// return false;
}

View File

@@ -0,0 +1,16 @@
#ifndef B3_SOUND_SOURCE_H
#define B3_SOUND_SOURCE_H
class b3SoundSource
{
struct b3SoundSourceInternalData* m_data;
public:
b3SoundSource();
virtual ~b3SoundSource();
virtual bool computeSamples(double *sampleBuffer, int numSamples, double sampleRate);
};
#endif //B3_SOUND_SOURCE_H

View File

@@ -0,0 +1,38 @@
project "App_TinyAudioExample"
language "C++"
kind "ConsoleApp"
includedirs {
".",
"../../src",
}
defines {"B3_USE_STANDALONE_EXAMPLE", "__STK_REALTIME__"}
files {
"**.cpp",
"**.h",
"../StandaloneMain/main_console_single_example.cpp",
}
if os.is("Windows") then
links {"winmm","Wsock32","dsound"}
defines {"WIN32","__WINDOWS_MM__","__LITTLE_ENDIAN__","__WINDOWS_DS__"}
end
if os.is("Linux") then initX11()
defines {"__OS_LINUX__","__LINUX_ALSA__","__LITTLE_ENDIAN__"}
links {"asound","pthread"}
end
if os.is("MacOSX") then
links{"Cocoa.framework"}
links{"CoreAudio.framework", "coreMIDI.framework", "Cocoa.framework"}
defines {"__OS_MACOSX__","__LITTLE_ENDIAN__"}
end