b3SoundSource.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include "b3SoundSource.h"
  2. #define MY2PI (2. * 3.14159265)
  3. #include <math.h>
  4. #include "Bullet3Common/b3FileUtils.h"
  5. #include "b3ReadWavFile.h"
  6. #include "b3ADSR.h"
  7. #include "b3Sound_C_Api.h"
  8. struct b3SoundOscillator
  9. {
  10. int m_type;
  11. double m_frequency;
  12. double m_amplitude;
  13. double m_phase;
  14. b3WavTicker m_wavTicker;
  15. double sampleSineWaveForm(double sampleRate)
  16. {
  17. while (m_phase >= MY2PI)
  18. m_phase -= MY2PI;
  19. double z = sinf(m_phase);
  20. double sample = m_amplitude * z;
  21. m_phase += MY2PI * (1. / sampleRate) * m_frequency;
  22. return sample;
  23. }
  24. double sampleSawWaveForm(double sampleRate)
  25. {
  26. while (m_phase >= MY2PI)
  27. m_phase -= MY2PI;
  28. double z = 2. * (m_phase) / MY2PI - 1.;
  29. double sample = m_amplitude * z;
  30. m_phase += MY2PI * (1. / sampleRate) * m_frequency;
  31. return sample;
  32. }
  33. void reset()
  34. {
  35. m_phase = 0;
  36. }
  37. b3SoundOscillator()
  38. : m_type(0),
  39. m_frequency(442.),
  40. m_amplitude(1),
  41. m_phase(0)
  42. {
  43. }
  44. };
  45. #define MAX_OSCILLATORS 2
  46. struct b3SoundSourceInternalData
  47. {
  48. b3SoundOscillator m_oscillators[MAX_OSCILLATORS];
  49. b3ADSR m_envelope;
  50. b3ReadWavFile* m_wavFilePtr;
  51. b3SoundSourceInternalData()
  52. : m_wavFilePtr(0)
  53. {
  54. }
  55. };
  56. b3SoundSource::b3SoundSource()
  57. {
  58. m_data = new b3SoundSourceInternalData();
  59. }
  60. b3SoundSource::~b3SoundSource()
  61. {
  62. delete m_data;
  63. }
  64. void b3SoundSource::setADSR(double attack, double decay, double sustain, double release)
  65. {
  66. m_data->m_envelope.setValues(attack, decay, sustain, release);
  67. }
  68. bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double sampleRate)
  69. {
  70. double* outputSamples = sampleBuffer;
  71. int numActive = 0;
  72. for (int i = 0; i < numSamples; i++)
  73. {
  74. double samples[MAX_OSCILLATORS] = {0};
  75. double env = m_data->m_envelope.tick();
  76. if (env)
  77. {
  78. for (int osc = 0; osc < MAX_OSCILLATORS; osc++)
  79. {
  80. if (m_data->m_oscillators[osc].m_type == 0)
  81. {
  82. samples[osc] += env * m_data->m_oscillators[osc].sampleSineWaveForm(sampleRate);
  83. numActive++;
  84. }
  85. if (m_data->m_oscillators[osc].m_type == 1)
  86. {
  87. samples[osc] += env * m_data->m_oscillators[osc].sampleSawWaveForm(sampleRate);
  88. numActive++;
  89. }
  90. if (m_data->m_oscillators[osc].m_type == 128)
  91. {
  92. int frame = 0;
  93. double data = env * m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFilePtr->tick(frame, &m_data->m_oscillators[osc].m_wavTicker);
  94. samples[osc] += data;
  95. numActive++;
  96. }
  97. }
  98. }
  99. else
  100. {
  101. for (int osc = 0; osc < MAX_OSCILLATORS; osc++)
  102. {
  103. if (m_data->m_oscillators[osc].m_type == 128)
  104. {
  105. m_data->m_oscillators[osc].m_wavTicker.finished_ = true;
  106. }
  107. }
  108. }
  109. //sample *= 1./double(MAX_OSCILLATORS);
  110. double sampleLeft = samples[0];
  111. double sampleRight = samples[1];
  112. if (sampleLeft != sampleRight)
  113. {
  114. }
  115. *outputSamples++ = sampleRight;
  116. *outputSamples++ = sampleLeft;
  117. }
  118. /* if (m_data->m_flags & looping)
  119. {
  120. for (int osc=0;osc<MAX_OSCILLATORS;osc++)
  121. {
  122. if (m_data->m_oscillators[osc].m_waveIn.isFinished())
  123. m_data->m_oscillators[osc].m_waveIn.reset();
  124. }
  125. }
  126. */
  127. return numActive > 0;
  128. // return false;
  129. }
  130. int b3SoundSource::getNumOscillators() const
  131. {
  132. return MAX_OSCILLATORS;
  133. }
  134. void b3SoundSource::setOscillatorType(int oscillatorIndex, int type)
  135. {
  136. m_data->m_oscillators[oscillatorIndex].m_type = type;
  137. }
  138. void b3SoundSource::setOscillatorFrequency(int oscillatorIndex, double frequency)
  139. {
  140. m_data->m_oscillators[oscillatorIndex].m_frequency = frequency;
  141. }
  142. void b3SoundSource::setOscillatorAmplitude(int oscillatorIndex, double amplitude)
  143. {
  144. m_data->m_oscillators[oscillatorIndex].m_amplitude = amplitude;
  145. }
  146. void b3SoundSource::setOscillatorPhase(int oscillatorIndex, double phase)
  147. {
  148. m_data->m_oscillators[oscillatorIndex].m_phase = phase;
  149. }
  150. bool b3SoundSource::isAvailable() const
  151. {
  152. //available if ADSR is idle and wavticker is finished
  153. return m_data->m_envelope.isIdle();
  154. }
  155. void b3SoundSource::startSound(bool autoKeyOff)
  156. {
  157. if (m_data->m_envelope.isIdle())
  158. {
  159. for (int osc = 0; osc < MAX_OSCILLATORS; osc++)
  160. {
  161. m_data->m_oscillators[osc].reset();
  162. if (m_data->m_oscillators[osc].m_type == B3_SOUND_SOURCE_WAV_FILE) // .m_wavTicker.finished_)
  163. {
  164. //test reverse playback of wav
  165. //m_data->m_oscillators[osc].m_wavTicker.rate_ *= -1;
  166. if (m_data->m_oscillators[osc].m_wavTicker.rate_ < 0)
  167. {
  168. m_data->m_oscillators[osc].m_wavTicker.time_ = m_data->m_wavFilePtr->getNumFrames() - 1.;
  169. }
  170. else
  171. {
  172. m_data->m_oscillators[osc].m_wavTicker.time_ = 0.f;
  173. }
  174. m_data->m_oscillators[osc].m_wavTicker.finished_ = false;
  175. }
  176. }
  177. }
  178. m_data->m_envelope.keyOn(autoKeyOff);
  179. }
  180. void b3SoundSource::stopSound()
  181. {
  182. m_data->m_envelope.keyOff();
  183. }
  184. bool b3SoundSource::setWavFile(int oscillatorIndex, b3ReadWavFile* wavFilePtr, int sampleRate)
  185. {
  186. {
  187. m_data->m_wavFilePtr = wavFilePtr;
  188. m_data->m_oscillators[oscillatorIndex].m_wavTicker = m_data->m_wavFilePtr->createWavTicker(sampleRate);
  189. // waveIn.openFile(resourcePath);
  190. double rate = 1.0;
  191. // rate = waveIn.getFileRate() / stkSampleRate;
  192. // waveIn.setRate( rate );
  193. // waveIn.ignoreSampleRateChange();
  194. // Find out how many channels we have.
  195. // int channels = waveIn.channelsOut();
  196. // m_data->m_oscillators[oscillatorIndex].m_frames.resize( 1, channels );
  197. m_data->m_oscillators[oscillatorIndex].m_type = 128;
  198. return true;
  199. }
  200. return false;
  201. }