mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-13 21:30:09 +00:00
move work on TinyAudio.
This commit is contained in:
parent
e6759cfa4f
commit
37a16f7e6b
@ -1,28 +1,76 @@
|
||||
#include "TinyAudioExample.h"
|
||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "Bullet3Common/b3HashMap.h"
|
||||
|
||||
|
||||
#include "b3SoundEngine.h"
|
||||
#include "b3SoundSource.h"
|
||||
#include <string>
|
||||
|
||||
///very basic hashable string implementation, compatible with b3HashMap
|
||||
struct MyHashString
|
||||
{
|
||||
std::string m_string;
|
||||
unsigned int m_hash;
|
||||
|
||||
B3_FORCE_INLINE unsigned int getHash()const
|
||||
{
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
MyHashString(const char* name)
|
||||
:m_string(name)
|
||||
{
|
||||
/* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
|
||||
static const unsigned int InitialFNV = 2166136261u;
|
||||
static const unsigned int FNVMultiple = 16777619u;
|
||||
|
||||
/* Fowler / Noll / Vo (FNV) Hash */
|
||||
unsigned int hash = InitialFNV;
|
||||
|
||||
for(int i = 0; m_string[i]; i++)
|
||||
{
|
||||
hash = hash ^ (m_string[i]); /* xor the low 8 bits */
|
||||
hash = hash * FNVMultiple; /* multiply by the magic number */
|
||||
}
|
||||
m_hash = hash;
|
||||
}
|
||||
|
||||
bool equals(const MyHashString& other) const
|
||||
{
|
||||
return (m_string == other.m_string);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
double base_frequency = 440.0;
|
||||
double base_pitch = 69.0;
|
||||
|
||||
double MidiPitch2Frequency(double incoming_note) {
|
||||
return base_frequency * pow (2.0, (incoming_note - base_pitch) / 12.0);
|
||||
}
|
||||
|
||||
double FrequencytoMidiPitch(double incoming_frequency) {
|
||||
return base_pitch + (12.0 * log(incoming_frequency / base_frequency) / log(2));
|
||||
}
|
||||
|
||||
|
||||
class TinyAudioExample : public CommonExampleInterface
|
||||
{
|
||||
|
||||
GUIHelperInterface* m_guiHelper;
|
||||
|
||||
|
||||
b3SoundEngine m_soundEngine;
|
||||
b3SoundSource* m_soundSource;
|
||||
int m_wavId;
|
||||
|
||||
b3HashMap<MyHashString,int> m_keyToSoundSource;
|
||||
|
||||
public:
|
||||
TinyAudioExample(struct GUIHelperInterface* helper)
|
||||
:m_guiHelper(helper),
|
||||
m_soundSource(0)
|
||||
:m_guiHelper(helper)
|
||||
{
|
||||
}
|
||||
|
||||
@ -32,21 +80,18 @@ public:
|
||||
|
||||
virtual void initPhysics()
|
||||
{
|
||||
m_soundEngine.init();
|
||||
int sampleRate = m_soundEngine.getSampleRate();
|
||||
int numSoundSources = 8;
|
||||
bool useRealTimeDac = true;
|
||||
|
||||
m_soundSource = new b3SoundSource();
|
||||
m_soundSource->setWavFile(1,"wav/xylophone.rosewood.ff.C5B5_1.wav", sampleRate);
|
||||
m_soundSource->setWavFile(0,"wav/xylophone.rosewood.ff.C5B5_1.wav", sampleRate);
|
||||
m_soundSource->setOscillatorAmplitude(0,1);
|
||||
m_soundSource->setOscillatorAmplitude(1,1);
|
||||
m_soundEngine.addSoundSource(m_soundSource);
|
||||
m_soundSource->startSound();
|
||||
m_soundEngine.init(numSoundSources, useRealTimeDac);
|
||||
|
||||
m_wavId = m_soundEngine.loadWavFile("wav/xylophone.rosewood.ff.C5B5_1.wav");
|
||||
int sampleRate = m_soundEngine.getSampleRate();
|
||||
}
|
||||
|
||||
virtual void exitPhysics()
|
||||
{
|
||||
m_soundSource->stopSound();
|
||||
|
||||
m_soundEngine.exit();
|
||||
}
|
||||
|
||||
@ -69,37 +114,75 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool keyboardCallback(int key, int state)
|
||||
{
|
||||
if (key=='v' || key=='b')
|
||||
if (key>='a' && key<='z')
|
||||
{
|
||||
char keyStr[2];
|
||||
keyStr[0] = (char)key;
|
||||
keyStr[1] = 0;
|
||||
MyHashString hs (keyStr);
|
||||
|
||||
if (state)
|
||||
if (state)
|
||||
{
|
||||
int soundSourceIndex = m_soundEngine.getAvailableSoundSource();
|
||||
if (soundSourceIndex>=0)
|
||||
{
|
||||
if (key=='b')
|
||||
{
|
||||
m_soundSource->setOscillatorFrequency(0, 442);
|
||||
m_soundSource->setOscillatorFrequency(1, 442);
|
||||
}
|
||||
if (key=='v')
|
||||
{
|
||||
m_soundSource->setOscillatorFrequency(0, 2*442);
|
||||
m_soundSource->setOscillatorFrequency(1, 2*442);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (state==1)
|
||||
{
|
||||
m_soundSource->startSound();
|
||||
|
||||
int note = key-(97-58);
|
||||
double freq = MidiPitch2Frequency(note);
|
||||
|
||||
b3SoundMessage msg;
|
||||
msg.m_type = B3_SOUND_SOURCE_SINE_OSCILLATOR;
|
||||
msg.m_frequency = freq;
|
||||
msg.m_amplitude = .25;
|
||||
|
||||
//msg.m_type = B3_SOUND_SOURCE_WAV_FILE;
|
||||
//msg.m_wavId = m_wavId;
|
||||
|
||||
m_soundEngine.startSound(soundSourceIndex, msg);
|
||||
m_keyToSoundSource.insert(hs,soundSourceIndex);
|
||||
//printf("soundSourceIndex:%d\n", soundSourceIndex);
|
||||
|
||||
#if 0
|
||||
b3SoundSource* soundSource = this->m_soundSourcesPool[soundSourceIndex];
|
||||
|
||||
soundSource->setOscillatorFrequency(0, freq );
|
||||
soundSource->setOscillatorFrequency(1, freq );
|
||||
soundSource->startSound();
|
||||
|
||||
{
|
||||
int* soundSourceIndexPtr = m_keyToSoundSource[hs];
|
||||
if (soundSourceIndexPtr)
|
||||
{
|
||||
int newIndex = *soundSourceIndexPtr;
|
||||
printf("just inserted: %d\n", newIndex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
int* soundSourceIndexPtr = m_keyToSoundSource[hs];
|
||||
if (soundSourceIndexPtr)
|
||||
{
|
||||
m_soundSource->stopSound();
|
||||
int soundSourceIndex = *soundSourceIndexPtr;
|
||||
//printf("releaseSound: %d\n", soundSourceIndex);
|
||||
m_soundEngine.releaseSound(soundSourceIndex);
|
||||
}
|
||||
#if 0
|
||||
if (soundSourceIndex>=0)
|
||||
{
|
||||
printf("releasing %d\n", soundSourceIndex);
|
||||
b3SoundSource* soundSource = this->m_soundSourcesPool[soundSourceIndex];
|
||||
soundSource->stopSound();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,9 +18,9 @@ b3ADSR::b3ADSR()
|
||||
{
|
||||
m_target = 0.0;
|
||||
m_value = 0.0;
|
||||
m_attackRate = 0.001;
|
||||
m_attackRate = 0.0001;
|
||||
m_decayRate = 0.00001;
|
||||
m_releaseRate = 0.005;
|
||||
m_releaseRate = 0.0005;
|
||||
m_sustainLevel = 0.5;
|
||||
m_state = ADSR_IDLE;
|
||||
}
|
||||
@ -78,7 +78,7 @@ double b3ADSR::tick()
|
||||
|
||||
bool b3ADSR::isIdle() const
|
||||
{
|
||||
return true;
|
||||
return m_state == ADSR_IDLE;
|
||||
}
|
||||
|
||||
void b3ADSR::keyOn()
|
||||
|
@ -141,8 +141,9 @@ int b3AudioListener::tick(void *outputBuffer,void *inputBuffer1,unsigned int nBu
|
||||
//simple mixer
|
||||
if (numActiveSources)
|
||||
{
|
||||
outs[0] *= .3/numActiveSources;
|
||||
outs[1] *= .3/numActiveSources;
|
||||
|
||||
outs[0] *= 1./4.;
|
||||
outs[1] *= 1./4.;
|
||||
}
|
||||
|
||||
*samples++ = outs[0];
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include "b3AudioListener.h"
|
||||
#include "b3SoundSource.h"
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
#include "b3ReadWavFile.h"
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
#include "Bullet3Common/b3HashMap.h"
|
||||
|
||||
// The default real-time audio input and output buffer size. If
|
||||
// clicks are occuring in the input and/or output sound stream, a
|
||||
@ -17,9 +20,17 @@ struct b3SoundEngineInternalData
|
||||
{
|
||||
b3AudioListener m_listener;
|
||||
RtAudio m_dac;
|
||||
bool m_useRealTimeDac;
|
||||
|
||||
b3AlignedObjectArray<b3SoundSource*> m_soundSources;
|
||||
b3HashMap<b3HashInt, b3ReadWavFile*> m_wavFiles;
|
||||
int m_wavFileUidGenerator;
|
||||
|
||||
b3SoundEngineInternalData()
|
||||
: m_useRealTimeDac(false),
|
||||
m_wavFileUidGenerator(123)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
b3SoundEngine::b3SoundEngine()
|
||||
@ -33,49 +44,113 @@ b3SoundEngine::~b3SoundEngine()
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
void b3SoundEngine::init()
|
||||
void b3SoundEngine::init(int maxNumSoundSources, bool useRealTimeDac)
|
||||
{
|
||||
for (int i = 0; i < maxNumSoundSources; i++)
|
||||
{
|
||||
b3SoundSource* source = new b3SoundSource();
|
||||
m_data->m_soundSources.push_back(source);
|
||||
m_data->m_listener.addSoundSource(source);
|
||||
}
|
||||
|
||||
RtAudioFormat format = ( sizeof(double) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = m_data->m_dac.getDefaultOutputDevice();
|
||||
parameters.nChannels = 2;
|
||||
this->m_data->m_useRealTimeDac = useRealTimeDac;
|
||||
|
||||
unsigned int bufferFrames = RT_BUFFER_SIZE;
|
||||
double sampleRate = m_data->m_listener.getSampleRate();
|
||||
if (useRealTimeDac)
|
||||
{
|
||||
RtAudioFormat format = (sizeof(double) == 8) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = m_data->m_dac.getDefaultOutputDevice();
|
||||
parameters.nChannels = 2;
|
||||
|
||||
m_data->m_dac.openStream( ¶meters, NULL, format, (unsigned int)sampleRate, &bufferFrames, &b3AudioListener::tick,
|
||||
(void *)m_data->m_listener.getTickData());
|
||||
unsigned int bufferFrames = RT_BUFFER_SIZE;
|
||||
double sampleRate = m_data->m_listener.getSampleRate();
|
||||
|
||||
m_data->m_dac.startStream();
|
||||
m_data->m_dac.openStream(¶meters, NULL, format, (unsigned int)sampleRate, &bufferFrames, &b3AudioListener::tick,
|
||||
(void*)m_data->m_listener.getTickData());
|
||||
|
||||
m_data->m_dac.startStream();
|
||||
}
|
||||
}
|
||||
|
||||
void b3SoundEngine::exit()
|
||||
{
|
||||
m_data->m_dac.closeStream();
|
||||
m_data->m_useRealTimeDac = false;
|
||||
|
||||
for (int i=0;i<m_data->m_soundSources.size();i++)
|
||||
for (int i = 0; i < m_data->m_soundSources.size(); i++)
|
||||
{
|
||||
m_data->m_listener.removeSoundSource(m_data->m_soundSources[i]);
|
||||
m_data->m_soundSources[i]->stopSound();
|
||||
delete m_data->m_soundSources[i];
|
||||
}
|
||||
m_data->m_soundSources.clear();
|
||||
}
|
||||
|
||||
|
||||
void b3SoundEngine::addSoundSource(b3SoundSource* source)
|
||||
int b3SoundEngine::getAvailableSoundSource()
|
||||
{
|
||||
m_data->m_soundSources.push_back(source);
|
||||
m_data->m_listener.addSoundSource(source);
|
||||
for (int i = 0; i < m_data->m_soundSources.size(); i++)
|
||||
{
|
||||
if (m_data->m_soundSources[i]->isAvailable())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void b3SoundEngine::removeSoundSource(b3SoundSource* source)
|
||||
void b3SoundEngine::startSound(int soundSourceIndex, b3SoundMessage msg)
|
||||
{
|
||||
m_data->m_soundSources.remove(source);
|
||||
b3SoundSource* soundSource = m_data->m_soundSources[soundSourceIndex];
|
||||
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;
|
||||
}
|
||||
case B3_SOUND_SOURCE_WAV_FILE:
|
||||
{
|
||||
b3ReadWavFile** wavFilePtr = m_data->m_wavFiles[msg.m_wavId];
|
||||
if (wavFilePtr)
|
||||
{
|
||||
b3ReadWavFile* wavFile = *wavFilePtr;
|
||||
soundSource->setWavFile(0,wavFile,getSampleRate());
|
||||
soundSource->setWavFile(1,wavFile,getSampleRate());
|
||||
soundSource->startSound();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void b3SoundEngine::releaseSound(int soundSourceIndex)
|
||||
{
|
||||
b3SoundSource* soundSource = m_data->m_soundSources[soundSourceIndex];
|
||||
soundSource->stopSound();
|
||||
}
|
||||
|
||||
int b3SoundEngine::loadWavFile(const char* fileName)
|
||||
{
|
||||
char resourcePath[1024];
|
||||
|
||||
if (b3ResourcePath::findResourcePath(fileName, resourcePath, 1024))
|
||||
{
|
||||
b3ReadWavFile* wavFile = new b3ReadWavFile();
|
||||
wavFile->getWavInfo(resourcePath);
|
||||
wavFile->resize();
|
||||
wavFile->read(0, true);
|
||||
wavFile->normalize(1);
|
||||
int wavUID = m_data->m_wavFileUidGenerator++;
|
||||
m_data->m_wavFiles.insert(wavUID, wavFile);
|
||||
return wavUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -83,5 +158,3 @@ double b3SoundEngine::getSampleRate() const
|
||||
{
|
||||
return m_data->m_listener.getSampleRate();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,20 @@
|
||||
|
||||
#include "Bullet3Common/b3Scalar.h"
|
||||
|
||||
struct b3SoundMessage
|
||||
{
|
||||
int m_type;//B3_SOUND_SOURCE_TYPE
|
||||
double m_amplitude;
|
||||
|
||||
double m_frequency;
|
||||
int m_wavId;
|
||||
|
||||
double m_attack;
|
||||
double m_decay;
|
||||
double m_sustain;
|
||||
double m_release;
|
||||
};
|
||||
|
||||
class b3SoundEngine
|
||||
{
|
||||
struct b3SoundEngineInternalData* m_data;
|
||||
@ -12,13 +26,12 @@ class b3SoundEngine
|
||||
b3SoundEngine();
|
||||
virtual ~b3SoundEngine();
|
||||
|
||||
void init();
|
||||
void init(int maxNumSoundSources, bool useRealTimeDac);
|
||||
void exit();
|
||||
|
||||
//int createListener();
|
||||
|
||||
void addSoundSource(class b3SoundSource* source);
|
||||
void removeSoundSource(class b3SoundSource* source);
|
||||
int getAvailableSoundSource();
|
||||
void startSound(int soundSourceIndex, b3SoundMessage msg);
|
||||
void releaseSound(int soundSourceIndex);
|
||||
|
||||
int loadWavFile(const char* fileName);
|
||||
|
||||
|
@ -3,10 +3,11 @@
|
||||
#define MY2PI (2.*3.14159265)
|
||||
#include <math.h>
|
||||
|
||||
#include "../Utils/b3ResourcePath.h"
|
||||
|
||||
#include "Bullet3Common/b3FileUtils.h"
|
||||
#include "b3ReadWavFile.h"
|
||||
#include "b3ADSR.h"
|
||||
#include "b3Sound_C_Api.h"
|
||||
|
||||
struct b3SoundOscillator
|
||||
{
|
||||
@ -62,7 +63,11 @@ struct b3SoundSourceInternalData
|
||||
{
|
||||
b3SoundOscillator m_oscillators[MAX_OSCILLATORS];
|
||||
b3ADSR m_envelope;
|
||||
b3ReadWavFile m_wavFile;
|
||||
b3ReadWavFile* m_wavFilePtr;
|
||||
b3SoundSourceInternalData()
|
||||
:m_wavFilePtr(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
b3SoundSource::b3SoundSource()
|
||||
@ -79,6 +84,7 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double
|
||||
{
|
||||
|
||||
double* outputSamples = sampleBuffer;
|
||||
int numActive = 0;
|
||||
|
||||
for (int i=0;i<numSamples;i++)
|
||||
{
|
||||
@ -87,32 +93,45 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double
|
||||
double env = m_data->m_envelope.tick();
|
||||
if (env)
|
||||
{
|
||||
for (int osc=0;osc<MAX_OSCILLATORS;osc++)
|
||||
for (int osc=0;osc<MAX_OSCILLATORS;osc++)
|
||||
{
|
||||
if (m_data->m_oscillators[osc].m_type == 0)
|
||||
{
|
||||
samples[osc] += env * m_data->m_oscillators[osc].sampleSineWaveForm(sampleRate);
|
||||
numActive++;
|
||||
}
|
||||
|
||||
if (m_data->m_oscillators[osc].m_type == 1)
|
||||
{
|
||||
samples[osc] += env * m_data->m_oscillators[osc].sampleSawWaveForm(sampleRate);
|
||||
numActive++;
|
||||
}
|
||||
|
||||
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);
|
||||
samples[osc] += data;
|
||||
numActive++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (m_data->m_oscillators[osc].m_type == 0)
|
||||
for (int osc=0;osc<MAX_OSCILLATORS;osc++)
|
||||
{
|
||||
samples[osc] += env * m_data->m_oscillators[osc].sampleSineWaveForm(sampleRate);
|
||||
if (m_data->m_oscillators[osc].m_type == 128)
|
||||
{
|
||||
m_data->m_oscillators[osc].m_wavTicker.finished_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_data->m_oscillators[osc].m_type == 1)
|
||||
{
|
||||
samples[osc] += env * m_data->m_oscillators[osc].sampleSawWaveForm(sampleRate);
|
||||
}
|
||||
|
||||
if (m_data->m_oscillators[osc].m_type == 128)
|
||||
{
|
||||
int frame = 0;
|
||||
double data = m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFile.tick(frame,&m_data->m_oscillators[osc].m_wavTicker);
|
||||
|
||||
samples[osc] += data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//sample *= 1./double(MAX_OSCILLATORS);
|
||||
|
||||
double sampleLeft = samples[0];
|
||||
double sampleRight = samples[1];
|
||||
if (sampleLeft != sampleRight)
|
||||
{
|
||||
}
|
||||
|
||||
*outputSamples++ = sampleRight;
|
||||
*outputSamples++ = sampleLeft ;
|
||||
@ -127,7 +146,7 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double
|
||||
}
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
return numActive>0;
|
||||
// return false;
|
||||
}
|
||||
|
||||
@ -152,22 +171,28 @@ void b3SoundSource::setOscillatorPhase(int oscillatorIndex, double phase)
|
||||
m_data->m_oscillators[oscillatorIndex].m_phase = phase;
|
||||
}
|
||||
|
||||
bool b3SoundSource::isAvailable() const
|
||||
{
|
||||
//available if ADSR is idle and wavticker is finished
|
||||
return m_data->m_envelope.isIdle();
|
||||
}
|
||||
|
||||
void b3SoundSource::startSound()
|
||||
{
|
||||
if (m_data->m_envelope.isIdle())
|
||||
{
|
||||
for (int osc=0;osc<MAX_OSCILLATORS;osc++)
|
||||
{
|
||||
static int reset = 0;
|
||||
printf("reset %d!\n",reset++);
|
||||
if (m_data->m_oscillators[osc].m_wavTicker.finished_)
|
||||
m_data->m_oscillators[osc].reset();
|
||||
|
||||
if (m_data->m_oscillators[osc].m_type == B3_SOUND_SOURCE_WAV_FILE)// .m_wavTicker.finished_)
|
||||
{
|
||||
m_data->m_oscillators[osc].reset();
|
||||
|
||||
//test reverse playback of wav
|
||||
m_data->m_oscillators[osc].m_wavTicker.rate_ *= -1;
|
||||
//m_data->m_oscillators[osc].m_wavTicker.rate_ *= -1;
|
||||
if (m_data->m_oscillators[osc].m_wavTicker.rate_<0)
|
||||
{
|
||||
m_data->m_oscillators[osc].m_wavTicker.time_ = m_data->m_wavFile.getNumFrames()-1.;
|
||||
m_data->m_oscillators[osc].m_wavTicker.time_ = m_data->m_wavFilePtr->getNumFrames()-1.;
|
||||
} else
|
||||
{
|
||||
m_data->m_oscillators[osc].m_wavTicker.time_ = 0.f;
|
||||
@ -187,18 +212,11 @@ void b3SoundSource::stopSound()
|
||||
}
|
||||
|
||||
|
||||
bool b3SoundSource::setWavFile(int oscillatorIndex, const char* fileName, int sampleRate)
|
||||
bool b3SoundSource::setWavFile(int oscillatorIndex, b3ReadWavFile* wavFilePtr, int sampleRate)
|
||||
{
|
||||
char resourcePath[1024];
|
||||
|
||||
if (b3ResourcePath::findResourcePath(fileName,resourcePath,1024))
|
||||
{
|
||||
|
||||
m_data->m_wavFile.getWavInfo(resourcePath);
|
||||
m_data->m_wavFile.resize();
|
||||
m_data->m_wavFile.read(0,true);
|
||||
m_data->m_wavFile.normalize(1);
|
||||
m_data->m_oscillators[oscillatorIndex].m_wavTicker = m_data->m_wavFile.createWavTicker(sampleRate);
|
||||
m_data->m_wavFilePtr = wavFilePtr;
|
||||
m_data->m_oscillators[oscillatorIndex].m_wavTicker = m_data->m_wavFilePtr->createWavTicker(sampleRate);
|
||||
|
||||
// waveIn.openFile(resourcePath);
|
||||
double rate = 1.0;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef B3_SOUND_SOURCE_H
|
||||
#define B3_SOUND_SOURCE_H
|
||||
|
||||
#include "b3Sound_C_Api.h"
|
||||
|
||||
|
||||
class b3SoundSource
|
||||
{
|
||||
struct b3SoundSourceInternalData* m_data;
|
||||
@ -18,11 +21,12 @@ public:
|
||||
void setOscillatorAmplitude(int oscillatorIndex, double amplitude);
|
||||
void setOscillatorPhase(int oscillatorIndex, double phase);
|
||||
|
||||
bool setWavFile(int oscillatorIndex, const char* fileName, int sampleRate);
|
||||
bool setWavFile(int oscillatorIndex, class b3ReadWavFile* wavFilePtr, int sampleRate);
|
||||
|
||||
void startSound();
|
||||
void stopSound();
|
||||
|
||||
bool isAvailable() const;
|
||||
};
|
||||
|
||||
#endif //B3_SOUND_SOURCE_H
|
||||
|
31
examples/TinyAudio/b3Sound_C_Api.h
Normal file
31
examples/TinyAudio/b3Sound_C_Api.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef B3_SOUND_C_API_H
|
||||
#define B3_SOUND_C_API_H
|
||||
|
||||
//todo: create a sound C-API
|
||||
|
||||
//create sound engine
|
||||
//destroy sound engine
|
||||
//getSoundSource
|
||||
//startSound
|
||||
//releaseSound
|
||||
//etc
|
||||
|
||||
enum B3_SOUND_SOURCE_TYPE
|
||||
{
|
||||
B3_SOUND_SOURCE_SINE_OSCILLATOR=1,
|
||||
B3_SOUND_SOURCE_SAW_OSCILLATOR,
|
||||
B3_SOUND_SOURCE_WAV_FILE,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif///B3_SOUND_C_API_H
|
Loading…
Reference in New Issue
Block a user