Просмотр исходного кода

Switched to mixing audio on demand from the audio interface

Ivan Safrin 10 лет назад
Родитель
Сommit
6bc2353d79

+ 14 - 2
include/polycode/core/PolySoundManager.h

@@ -32,15 +32,27 @@
 #define POLY_MIX_BUFFER_SIZE (POLY_FRAMES_PER_BUFFER*POLY_CIRCULAR_BUFFER_SIZE)
 
 namespace Polycode {
+    
+    class _PolyExport AudioMixer {
+        public:
+            void mixIntoBuffer(int16_t *buffer, unsigned int numSamples);
+            std::vector<Sound*> sounds;
+            Number globalVolume;
+    };
 	
     class _PolyExport AudioInterface {
         public:
             AudioInterface();
             void addToBuffer(int16_t *data, unsigned int count);
+            void setMixer(AudioMixer *mixer);
+            AudioMixer *getMixer();
         
             int16_t bufferData[POLY_NUM_CHANNELS][POLY_FRAMES_PER_BUFFER*POLY_CIRCULAR_BUFFER_SIZE];
             unsigned int readOffset;
             unsigned int writeOffset;
+        
+        protected:
+            AudioMixer *mixer;
     };
     
     
@@ -72,15 +84,15 @@ namespace Polycode {
 		
 	protected:
 		
+        AudioMixer *mixer;
         AudioInterface *audioInterface;
         
         int16_t mixBuffer[POLY_MIX_BUFFER_SIZE*POLY_NUM_CHANNELS];
         
-        Number globalVolume;
         Number testVal;
         Number leftOver;
         
-        std::vector<Sound*> sounds;
+       
         int recordingBufferSize;
         int recordingBufferRate;
 	};

BIN
lib/osx/libPolycore.a


+ 1 - 9
src/core/PolyPAAudioInterface.cpp

@@ -79,15 +79,7 @@ int PAAudioInterface::paCallback(const void *inputBuffer, void *outputBuffer,
     PAAudioInterface *audioInterface = (PAAudioInterface*) userData;
     if(outputBuffer) {
         int16_t *out = (int16_t*)outputBuffer;
-        for(int i=0; i < framesPerBuffer; i++) {
-            for(int b=0; b < POLY_NUM_CHANNELS; b++) {
-                *out++ = audioInterface->bufferData[b][audioInterface->readOffset];
-            }
-            audioInterface->readOffset++;
-            if(audioInterface->readOffset >= POLY_FRAMES_PER_BUFFER * POLY_CIRCULAR_BUFFER_SIZE) {
-                audioInterface->readOffset = 0;
-            }
-        }
+        audioInterface->getMixer()->mixIntoBuffer(out, framesPerBuffer);
     }
     return 0;
 }

+ 46 - 49
src/core/PolySoundManager.cpp

@@ -30,12 +30,13 @@ using namespace Polycode;
 SoundManager::SoundManager() {
     audioInterface = NULL;
     testVal = 0.0;
-    globalVolume = 1.0;
     leftOver = 0.0;
+    mixer = new AudioMixer();
+    mixer->globalVolume = 1.0;    
 }
 
 void SoundManager::setGlobalVolume(Number globalVolume) {
-    this->globalVolume = globalVolume;
+    mixer->globalVolume = globalVolume;
 }
 
 void SoundManager::setListenerPosition(Vector3 position) {
@@ -103,13 +104,13 @@ Sound *SoundManager::stopRecording(bool generateFloatBuffer) {
 }
 
 void SoundManager::registerSound(Sound *sound) {
-    sounds.push_back(sound);
+    mixer->sounds.push_back(sound);
 }
 
 void SoundManager::unregisterSound(Sound *sound) {
-    for(int i=0; i < sounds.size(); i++) {
-        if(sounds[i] == sound) {
-            sounds.erase(sounds.begin()+i);
+    for(int i=0; i < mixer->sounds.size(); i++) {
+        if(mixer->sounds[i] == sound) {
+            mixer->sounds.erase(mixer->sounds.begin()+i);
             return;
         }
     }
@@ -117,6 +118,7 @@ void SoundManager::unregisterSound(Sound *sound) {
 
 void SoundManager::setAudioInterface(AudioInterface *audioInterface) {
     this->audioInterface = audioInterface;
+    audioInterface->setMixer(mixer);
 }
 
 
@@ -139,8 +141,16 @@ void AudioInterface::addToBuffer(int16_t *data, unsigned int count) {
     }
 }
 
-inline Number mixSamples(Number A, Number B) {
+void AudioInterface::setMixer(AudioMixer *mixer) {
+    this->mixer = mixer;
+}
 
+AudioMixer *AudioInterface::getMixer() {
+    return mixer;
+}
+
+inline Number mixSamples(Number A, Number B) {
+    
     if (A < 0 && B < 0 ) {
         return  (A + B) - (A * B)/-1.0;
     } else if (A > 0 && B > 0 ) {
@@ -150,58 +160,45 @@ inline Number mixSamples(Number A, Number B) {
     }
 }
 
-void SoundManager::Update() {
-    Number elapsed = Services()->getCore()->getElapsed();
+void AudioMixer::mixIntoBuffer(int16_t *buffer, unsigned int numSamples) {
     
-    if(audioInterface) {
-
-        // mix sounds
-        unsigned int numSamples = ((Number)POLY_AUDIO_FREQ)*(elapsed);
-        
-        // align to 64 samples
-       // numSamples = numSamples-(numSamples%64);
+    for(int i=0; i < sounds.size(); i++) {
+        sounds[i]->updateStream(numSamples);
+    }
+    
+    int16_t *bufferPtr = buffer;
+    for(int i=0; i < numSamples; i++) {
         
+        Number mixResults[POLY_NUM_CHANNELS];
+        memset(mixResults, 0, sizeof(Number) * POLY_NUM_CHANNELS);
         
-        if(numSamples > POLY_MIX_BUFFER_SIZE) {
-            numSamples = POLY_MIX_BUFFER_SIZE;
-        }
-
+        int mixNum = 0;
         for(int i=0; i < sounds.size(); i++) {
-            sounds[i]->updateStream(numSamples);
-        }
-        
-        int16_t *bufferPtr = mixBuffer;
-        for(int i=0; i < numSamples; i++) {
-            
-            Number mixResults[POLY_NUM_CHANNELS];
-            memset(mixResults, 0, sizeof(Number) * POLY_NUM_CHANNELS);
-            
-            int mixNum = 0;
-            for(int i=0; i < sounds.size(); i++) {
-                if(sounds[i]->isPlaying()) {
-                    for(int c=0; c < POLY_NUM_CHANNELS; c++) {
-                        Number A = mixResults[c];
-                        Number B = sounds[i]->getSampleAsNumber(sounds[i]->getOffset(), c);
-                        
-                        if(mixNum == 0) {
-                            mixResults[c] = B;
-                        } else {
-                            mixResults[c] = mixSamples(A, B);
-                        }
+            if(sounds[i]->isPlaying()) {
+                for(int c=0; c < POLY_NUM_CHANNELS; c++) {
+                    Number sampleA = mixResults[c];
+                    Number sampleB = sounds[i]->getSampleAsNumber(sounds[i]->getOffset(), c);
+                    
+                    if(mixNum == 0) {
+                        mixResults[c] = sampleB;
+                    } else {
+                        mixResults[c] = mixSamples(sampleA, sampleB);
                     }
-                    sounds[i]->setOffset(sounds[i]->getOffset()+1);
-                    mixNum++;
                 }
-            }
-            
-            for(int c=0; c < POLY_NUM_CHANNELS; c++) {
-                *bufferPtr = (int16_t)(((Number)INT16_MAX) * (mixResults[c] * globalVolume));
-                bufferPtr++;
+                sounds[i]->setOffset(sounds[i]->getOffset()+1);
+                mixNum++;
             }
         }
         
-        audioInterface->addToBuffer(mixBuffer, numSamples);
+        for(int c=0; c < POLY_NUM_CHANNELS; c++) {
+            *bufferPtr = (int16_t)(((Number)INT16_MAX) * (mixResults[c] * globalVolume));
+            bufferPtr++;
+        }
     }
+    
+}
+
+void SoundManager::Update() {
 }
 
 SoundManager::~SoundManager() {