diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 304fc6b2cf..ef21f208d0 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -187,7 +187,7 @@ unsigned int AudioRingBuffer::samplesAvailable() const { } } -void AudioRingBuffer::addSilentFrame(int numSilentSamples) { +int AudioRingBuffer::addSilentFrame(int numSilentSamples) { int samplesRoomFor = _sampleCapacity - samplesAvailable(); if (numSilentSamples > samplesRoomFor) { @@ -201,14 +201,14 @@ printf("_nextOutput at index %d\n", _nextOutput - _buffer); // push the _endOfLastWrite to the correct spot if (_endOfLastWrite + numSilentSamples <= _buffer + _arrayLength) { memset(_endOfLastWrite, 0, numSilentSamples * sizeof(int16_t)); - _endOfLastWrite += numSilentSamples; } else { int numSamplesToEnd = (_buffer + _arrayLength) - _endOfLastWrite; memset(_endOfLastWrite, 0, numSamplesToEnd * sizeof(int16_t)); memset(_buffer, 0, (numSilentSamples - numSamplesToEnd) * sizeof(int16_t)); - - _endOfLastWrite = _buffer + (numSilentSamples - numSamplesToEnd); } + _endOfLastWrite = shiftedPositionAccomodatingWrap(_endOfLastWrite, numSilentSamples); + + return numSilentSamples * sizeof(int16_t); } bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const { diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 33f9ada0bd..abe9cb044c 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -73,7 +73,7 @@ public: bool hasStarted() const { return _hasStarted; } - void addSilentFrame(int numSilentSamples); + int addSilentFrame(int numSilentSamples); protected: // disallow copying of AudioRingBuffer objects AudioRingBuffer(const AudioRingBuffer&); diff --git a/tests/audio/CMakeLists.txt b/tests/audio/CMakeLists.txt new file mode 100644 index 0000000000..5c5178cb71 --- /dev/null +++ b/tests/audio/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 2.8) + +if (WIN32) + cmake_policy (SET CMP0020 NEW) +endif (WIN32) + +set(TARGET_NAME audio-tests) + +set(ROOT_DIR ../..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/") + +#find_package(Qt5Network REQUIRED) +#find_package(Qt5Script REQUIRED) +#find_package(Qt5Widgets REQUIRED) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME} TRUE) + +include(${MACRO_DIR}/AutoMTC.cmake) +auto_mtc(${TARGET_NAME} ${ROOT_DIR}) + +#qt5_use_modules(${TARGET_NAME} Network Script Widgets) + +#include glm +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + +# link in the shared libraries +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(networking ${TARGET_NAME} ${ROOT_DIR}) + +IF (WIN32) + target_link_libraries(${TARGET_NAME} Winmm Ws2_32) +ENDIF(WIN32) + diff --git a/tests/audio/src/AudioRingBufferTests.cpp b/tests/audio/src/AudioRingBufferTests.cpp new file mode 100644 index 0000000000..506e81e13e --- /dev/null +++ b/tests/audio/src/AudioRingBufferTests.cpp @@ -0,0 +1,146 @@ +// +// AudioRingBufferTests.cpp +// tests/audio/src +// +// Created by Yixin Wang on 6/24/2014 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AudioRingBufferTests.h" + +#include "SharedUtil.h" + +void AudioRingBufferTests::assertBufferSize(const AudioRingBuffer& buffer, int samples) { + if (buffer.samplesAvailable() != samples) { + qDebug("Unexpected num samples available! Exptected: %d Actual: %d\n", samples, buffer.samplesAvailable()); + } +} + +void AudioRingBufferTests::runAllTests() { + + int16_t writeData[10000]; + for (int i = 0; i < 10000; i++) { writeData[i] = i; } + int writeIndexAt; + + int16_t readData[10000]; + int readIndexAt; + + + AudioRingBuffer ringBuffer(10); // makes buffer of 100 int16_t samples + for (int T = 0; T < 300; T++) { + + writeIndexAt = 0; + readIndexAt = 0; + + // write 73 samples, 73 samples in buffer + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 73) / sizeof(int16_t); + assertBufferSize(ringBuffer, 73); + + // read 43 samples, 30 samples in buffer + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 43) / sizeof(int16_t); + assertBufferSize(ringBuffer, 30); + + // write 70 samples, 100 samples in buffer (full) + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 70) / sizeof(int16_t); + assertBufferSize(ringBuffer, 100); + + // read 100 samples, 0 samples in buffer (empty) + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 100) / sizeof(int16_t); + assertBufferSize(ringBuffer, 0); + + + // verify 143 samples of read data + for (int i = 0; i < 143; i++) { + if (readData[i] != i) { + qDebug("first readData[%d] incorrect! Expcted: %d Actual: %d", i, i, readData[i]); + return; + } + } + + + writeIndexAt = 0; + readIndexAt = 0; + + // write 59 samples, 59 samples in buffer + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 59) / sizeof(int16_t); + assertBufferSize(ringBuffer, 59); + + // write 99 samples, 100 samples in buffer + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 99) / sizeof(int16_t); + assertBufferSize(ringBuffer, 100); + + // read 100 samples, 0 samples in buffer + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 100) / sizeof(int16_t); + assertBufferSize(ringBuffer, 0); + + // verify 100 samples of read data + for (int i = 0; i < 100; i++) { + readData[i] = writeIndexAt - 100 + i; + } + + + + + writeIndexAt = 0; + readIndexAt = 0; + + // write 77 samples, 77 samples in buffer + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 77) / sizeof(int16_t); + assertBufferSize(ringBuffer, 77); + + // write 24 samples, 100 samples in buffer (overwrote one sample: "0") + writeIndexAt += ringBuffer.writeSamples(&writeData[writeIndexAt], 24) / sizeof(int16_t); + assertBufferSize(ringBuffer, 100); + + // write 29 silent samples, 100 samples in buffer, make sure non were added + int samplesWritten; + if ((samplesWritten = ringBuffer.addSilentFrame(29)) != 0) { + qDebug("addSilentFrame(29) incorrect! Expected: 0 Actual: %d", samplesWritten); + return; + } + assertBufferSize(ringBuffer, 100); + + // read 3 samples, 97 samples in buffer (expect to read "1", "2", "3") + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 3) / sizeof(int16_t); + for (int i = 0; i < 3; i++) { + if (readData[i] != i + 1) { + qDebug("Second readData[%d] incorrect! Expcted: %d Actual: %d", i, i + 1, readData[i]); + return; + } + } + assertBufferSize(ringBuffer, 97); + + // write 4 silent samples, 100 samples in buffer + if ((samplesWritten = ringBuffer.addSilentFrame(4) / sizeof(int16_t)) != 3) { + qDebug("addSilentFrame(4) incorrect! Exptected: 3 Actual: %d", samplesWritten); + return; + } + assertBufferSize(ringBuffer, 100); + + // read back 97 samples (the non-silent samples), 3 samples in buffer (expect to read "4" thru "100") + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 97) / sizeof(int16_t); + for (int i = 3; i < 100; i++) { + if (readData[i] != i + 1) { + qDebug("third readData[%d] incorrect! Expcted: %d Actual: %d", i, i + 1, readData[i]); + return; + } + } + assertBufferSize(ringBuffer, 3); + + // read back 3 silent samples, 0 samples in buffer + readIndexAt += ringBuffer.readSamples(&readData[readIndexAt], 3) / sizeof(int16_t); + for (int i = 100; i < 103; i++) { + if (readData[i] != 0) { + qDebug("Fourth readData[%d] incorrect! Expcted: %d Actual: %d", i, 0, readData[i]); + return; + } + } + assertBufferSize(ringBuffer, 0); + } + + qDebug() << "PASSED"; +} + diff --git a/tests/audio/src/AudioRingBufferTests.h b/tests/audio/src/AudioRingBufferTests.h new file mode 100644 index 0000000000..20cbe74699 --- /dev/null +++ b/tests/audio/src/AudioRingBufferTests.h @@ -0,0 +1,25 @@ +// +// AudioRingBufferTests.h +// tests/audio/src +// +// Created by Yixin Wang on 6/24/2014 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AudioRingBufferTests_h +#define hifi_AudioRingBufferTests_h + +#include "AudioRingBuffer.h" + + +namespace AudioRingBufferTests { + + void runAllTests(); + + void assertBufferSize(const AudioRingBuffer& buffer, int samples); +}; + +#endif // hifi_AudioRingBufferTests_h diff --git a/tests/audio/src/main.cpp b/tests/audio/src/main.cpp new file mode 100644 index 0000000000..bf798982a9 --- /dev/null +++ b/tests/audio/src/main.cpp @@ -0,0 +1,18 @@ +// +// main.cpp +// tests/audio/src +// +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AudioRingBufferTests.h" +#include + +int main(int argc, char** argv) { + AudioRingBufferTests::runAllTests(); + getchar(); + return 0; +}