From 17bbe8216ae61624a20e2685e9fec2ece42f1918 Mon Sep 17 00:00:00 2001 From: Steve Lascos Date: Wed, 24 Jan 2018 21:14:57 -0500 Subject: [PATCH] Fixed a problem with INTERNAL memory on initial filling of RingBuffer --- src/AudioEffectAnalogDelay.cpp | 2 +- src/LibBasicFunctions.cpp | 32 ++++++++++++++++++++++---------- src/LibBasicFunctions.h | 13 +++++++------ 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/AudioEffectAnalogDelay.cpp b/src/AudioEffectAnalogDelay.cpp index 73d9b6a..cfac170 100644 --- a/src/AudioEffectAnalogDelay.cpp +++ b/src/AudioEffectAnalogDelay.cpp @@ -179,7 +179,7 @@ void AudioEffectAnalogDelay::processMidi(int channel, int control, int value) if ((m_midiConfig[MIDI_ENABLE][MIDI_CHANNEL] == channel) && (m_midiConfig[MIDI_ENABLE][MIDI_CONTROL] == control)) { // Enable - if (val >= 65) { enable(); Serial.println(String("AudioEffectAnalogDelay::enable: ON") + value); } + if (value >= 65) { enable(); Serial.println(String("AudioEffectAnalogDelay::enable: ON") + value); } else { disable(); Serial.println(String("AudioEffectAnalogDelay::enable: OFF") + value); } return; } diff --git a/src/LibBasicFunctions.cpp b/src/LibBasicFunctions.cpp index dba786e..67debd6 100644 --- a/src/LibBasicFunctions.cpp +++ b/src/LibBasicFunctions.cpp @@ -32,7 +32,7 @@ size_t calcOffset(QueuePosition position) return (position.index*AUDIO_BLOCK_SAMPLES) + position.offset; } -audio_block_t alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t* wet, float mix) +void alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t* wet, float mix) { for (int i=0; i< AUDIO_BLOCK_SAMPLES; i++) { out->data[i] = (dry->data[i] * (1 - mix)) + (wet->data[i] * mix); @@ -89,6 +89,7 @@ audio_block_t* AudioDelay::addBlock(audio_block_t *block) // add the new buffer m_ringBuffer->push_back(block); return blockToRelease; + } else { // EXTERNAL memory if (!m_slot) { Serial.println("addBlock(): m_slot is not valid"); } @@ -126,35 +127,46 @@ audio_block_t* AudioDelay::getBlock(size_t index) bool AudioDelay::getSamples(audio_block_t *dest, size_t offset, size_t numSamples) { - if (!dest) return false; + if (!dest) { + Serial.println("getSamples(): dest is invalid"); + return false; + } if (m_type == (MemType::MEM_INTERNAL)) { QueuePosition position = calcQueuePosition(offset); size_t index = position.index; + audio_block_t *currentQueue0 = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index)); + // The latest buffer is at the back. We need index+1 counting from the back. + audio_block_t *currentQueue1 = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index+1)); + + // check if either queue is invalid, if so just zero the destination buffer + if ( (!currentQueue0) || (!currentQueue0) ) { + // a valid entry is not in all queue positions while it is filling, use zeros + memset(static_cast(dest->data), 0, numSamples * sizeof(int16_t)); + return true; + } + if (position.offset == 0) { // single transfer - audio_block_t *currentQueue = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index)); - memcpy(static_cast(dest->data), static_cast(currentQueue->data), numSamples * sizeof(int16_t)); + memcpy(static_cast(dest->data), static_cast(currentQueue0->data), numSamples * sizeof(int16_t)); return true; } // Otherwise we need to break the transfer into two memcpy because it will go across two source queues. // Audio is stored in reverse order. That means the first sample (in time) goes in the last location in the audio block. int16_t *destStart = dest->data; - audio_block_t *currentQueue; int16_t *srcStart; // Break the transfer into two. Copy the 'older' data first then the 'newer' data with respect to current time. - currentQueue = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index+1)); // The latest buffer is at the back. We need index+1 counting from the back. - srcStart = (currentQueue->data + AUDIO_BLOCK_SAMPLES - position.offset); + //currentQueue = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index+1)); // The latest buffer is at the back. We need index+1 counting from the back. + srcStart = (currentQueue1->data + AUDIO_BLOCK_SAMPLES - position.offset); size_t numData = position.offset; memcpy(static_cast(destStart), static_cast(srcStart), numData * sizeof(int16_t)); - - currentQueue = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index)); // now grab the queue where the 'first' data sample was + //currentQueue = m_ringBuffer->at(m_ringBuffer->get_index_from_back(index)); // now grab the queue where the 'first' data sample was destStart += numData; // we already wrote numData so advance by this much. - srcStart = (currentQueue->data); + srcStart = (currentQueue0->data); numData = AUDIO_BLOCK_SAMPLES - numData; memcpy(static_cast(destStart), static_cast(srcStart), numData * sizeof(int16_t)); diff --git a/src/LibBasicFunctions.h b/src/LibBasicFunctions.h index cdaa811..5b2dc3b 100644 --- a/src/LibBasicFunctions.h +++ b/src/LibBasicFunctions.h @@ -71,7 +71,7 @@ size_t calcOffset(QueuePosition position); void clearAudioBlock(audio_block_t *block); -audio_block_t alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t* wet, float mix); +void alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t* wet, float mix); template @@ -164,7 +164,7 @@ public: /// Construct a RingBuffer of specified max size /// @param maxSize number of entries in ring buffer RingBuffer(const size_t maxSize) : m_maxSize(maxSize) { - m_buffer = new T[maxSize]; + m_buffer = new T[maxSize](); } virtual ~RingBuffer(){ if (m_buffer) delete [] m_buffer; @@ -199,7 +199,7 @@ public: if (m_size == 0) { // buffer is empty - Serial.println("RingBuffer::pop_front: buffer is empty\n"); + //Serial.println("RingBuffer::pop_front: buffer is empty\n"); return -1; } if (m_tail < m_maxSize-1) { @@ -208,7 +208,7 @@ public: m_tail = 0; } m_size--; - Serial.println(String("RingBuffer::pop_front: ") + m_head + String(":") + m_tail + String(":") + m_size); + //Serial.println(String("RingBuffer::pop_front: ") + m_head + String(":") + m_tail + String(":") + m_size); return 0; } @@ -264,10 +264,11 @@ public: return m_buffer[index]; } - /// DEBUG: Prints the status of the Ringbuffer + /// DEBUG: Prints the status of the Ringbuffer. NOte using this much printing will usually cause audio glitches void print() const { for (int idx=0; idxdata); + Serial.print(idx + String(" address: ")); Serial.print((uint32_t)m_buffer[idx], HEX); + Serial.print(" data: "); Serial.println((uint32_t)m_buffer[idx]->data, HEX); } } private: