This commit is contained in:
Philip Rosedale 2014-07-08 17:09:50 -07:00
commit a7ad803a7f
11 changed files with 54 additions and 44 deletions

View file

@ -32,14 +32,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed. # Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
if (APPLE)
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
if (DARWIN_VERSION GREATER 12)
set(CMAKE_CXX_FLAGS "-stdlib=libstdc++")
endif (DARWIN_VERSION GREATER 12)
endif (APPLE)
# targets not supported on windows # targets not supported on windows
if (NOT WIN32) if (NOT WIN32)
add_subdirectory(animation-server) add_subdirectory(animation-server)

View file

@ -138,11 +138,14 @@ void AudioMixerClientData::pushBuffersAfterFrameSend() {
// this was a used buffer, push the output pointer forwards // this was a used buffer, push the output pointer forwards
PositionalAudioRingBuffer* audioBuffer = *i; PositionalAudioRingBuffer* audioBuffer = *i;
const int INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD = 100;
if (audioBuffer->willBeAddedToMix()) { if (audioBuffer->willBeAddedToMix()) {
audioBuffer->shiftReadPosition(audioBuffer->getSamplesPerFrame()); audioBuffer->shiftReadPosition(audioBuffer->getSamplesPerFrame());
audioBuffer->setWillBeAddedToMix(false); audioBuffer->setWillBeAddedToMix(false);
} else if (audioBuffer->getType() == PositionalAudioRingBuffer::Injector } else if (audioBuffer->getType() == PositionalAudioRingBuffer::Injector
&& audioBuffer->hasStarted() && audioBuffer->isStarved()) { && audioBuffer->hasStarted() && audioBuffer->isStarved()
&& audioBuffer->getConsecutiveNotMixedCount() > INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD) {
// this is an empty audio buffer that has starved, safe to delete // this is an empty audio buffer that has starved, safe to delete
// also delete its sequence number stats // also delete its sequence number stats
QUuid streamIdentifier = ((InjectedAudioRingBuffer*)audioBuffer)->getStreamIdentifier(); QUuid streamIdentifier = ((InjectedAudioRingBuffer*)audioBuffer)->getStreamIdentifier();

View file

@ -26,8 +26,8 @@ else ()
set(RTMIDI_SEARCH_DIRS "${RTMIDI_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/rtmidi") set(RTMIDI_SEARCH_DIRS "${RTMIDI_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/rtmidi")
find_path(RTMIDI_INCLUDE_DIR RtMidi.h PATH_SUFFIXES include HINTS ${RTMIDI_SEARCH_DIRS}) find_path(RTMIDI_INCLUDE_DIR RtMidi.h PATH_SUFFIXES include HINTS ${RTMIDI_SEARCH_DIRS})
find_file(RTMIDI_CPP NAMES RtMidi.cpp PATH_SUFFIXES src HINTS ${RTMIDI_SEARCH_DIRS}) find_library(RTMIDI_LIBRARY NAMES rtmidi PATH_SUFFIXES lib HINTS ${RTMIDI_SEARCH_DIRS})
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RTMIDI DEFAULT_MSG RTMIDI_INCLUDE_DIR RTMIDI_CPP) find_package_handle_standard_args(RTMIDI DEFAULT_MSG RTMIDI_INCLUDE_DIR RTMIDI_LIBRARY)
endif () endif ()

View file

@ -111,16 +111,6 @@ if (APPLE)
SET(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/interface.icns") SET(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/interface.icns")
endif() endif()
# RtMidi for scripted MIDI control
find_package(RtMidi)
if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI)
add_definitions(-DHAVE_RTMIDI)
include_directories(SYSTEM ${RTMIDI_INCLUDE_DIR})
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${RTMIDI_CPP}")
endif ()
# create the executable, make it a bundle on OS X # create the executable, make it a bundle on OS X
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM}) add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
@ -151,6 +141,7 @@ find_package(Sixense)
find_package(Visage) find_package(Visage)
find_package(ZLIB) find_package(ZLIB)
find_package(Qxmpp) find_package(Qxmpp)
find_package(RtMidi)
# include the Sixense library for Razer Hydra if available # include the Sixense library for Razer Hydra if available
if (SIXENSE_FOUND AND NOT DISABLE_SIXENSE) if (SIXENSE_FOUND AND NOT DISABLE_SIXENSE)
@ -223,11 +214,18 @@ if (QXMPP_FOUND AND NOT DISABLE_QXMPP)
target_link_libraries(${TARGET_NAME} "${QXMPP_LIBRARY}") target_link_libraries(${TARGET_NAME} "${QXMPP_LIBRARY}")
endif (QXMPP_FOUND AND NOT DISABLE_QXMPP) endif (QXMPP_FOUND AND NOT DISABLE_QXMPP)
# link CoreMIDI if we're using RtMidi # and with RtMidi for RtMidi control
if (RTMIDI_FOUND AND APPLE) if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI)
find_library(CoreMIDI CoreMIDI)
add_definitions(-D__MACOSX_CORE__) add_definitions(-DHAVE_RTMIDI)
target_link_libraries(${TARGET_NAME} ${CoreMIDI}) include_directories(SYSTEM ${RTMIDI_INCLUDE_DIR})
target_link_libraries(${TARGET_NAME} "${RTMIDI_LIBRARY}")
if (APPLE)
find_library(CoreMIDI CoreMIDI)
add_definitions(-D__MACOSX_CORE__)
target_link_libraries(${TARGET_NAME} ${CoreMIDI})
endif()
endif() endif()
# include headers for interface and InterfaceConfig. # include headers for interface and InterfaceConfig.

View file

@ -7,7 +7,9 @@ Stephen Birarda, June 30, 2014
2. Copy RtMidi.h to externals/rtmidi/include. 2. Copy RtMidi.h to externals/rtmidi/include.
3. Copy RtMidi.cpp to externals/rtmidi/src 3. Compile the RtMidi library.
3. Copy either librtmidi.dylib (dynamic) or librtmidi.a (static) to externals/rtmidi/lib
4. Delete your build directory, run cmake and build, and you should be all set. 4. Delete your build directory, run cmake and build, and you should be all set.

View file

@ -67,7 +67,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
_proceduralAudioOutput(NULL), _proceduralAudioOutput(NULL),
_proceduralOutputDevice(NULL), _proceduralOutputDevice(NULL),
_inputRingBuffer(0), _inputRingBuffer(0),
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO), _ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO, false, 100),
_isStereoInput(false), _isStereoInput(false),
_averagedLatency(0.0), _averagedLatency(0.0),
_measuredJitter(0), _measuredJitter(0),
@ -869,14 +869,16 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) {
_numFramesDisplayStarve = 10; _numFramesDisplayStarve = 10;
} }
// if there is anything in the ring buffer, decide what to do int numNetworkOutputSamples;
if (_ringBuffer.samplesAvailable() > 0) { if (Menu::getInstance()->isOptionChecked(MenuOption::DisableQAudioOutputOverflowCheck)) {
numNetworkOutputSamples = _ringBuffer.samplesAvailable();
int numNetworkOutputSamples = _ringBuffer.samplesAvailable(); } else {
int numDeviceOutputSamples = numNetworkOutputSamples / networkOutputToOutputRatio; int numSamplesAudioOutputRoomFor = _audioOutput->bytesFree() / sizeof(int16_t);
numNetworkOutputSamples = std::min(_ringBuffer.samplesAvailable(), (int)(numSamplesAudioOutputRoomFor * networkOutputToOutputRatio));
QByteArray outputBuffer; }
outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t));
// if there is data in the ring buffer and room in the audio output, decide what to do
if (numNetworkOutputSamples > 0) {
int numSamplesNeededToStartPlayback = std::min(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2), int numSamplesNeededToStartPlayback = std::min(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2),
_ringBuffer.getSampleCapacity()); _ringBuffer.getSampleCapacity());
@ -885,6 +887,11 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) {
// We are still waiting for enough samples to begin playback // We are still waiting for enough samples to begin playback
// qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback; // qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback;
} else { } else {
int numDeviceOutputSamples = numNetworkOutputSamples / networkOutputToOutputRatio;
QByteArray outputBuffer;
outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t));
// We are either already playing back, or we have enough audio to start playing back. // We are either already playing back, or we have enough audio to start playing back.
//qDebug() << "pushing " << numNetworkOutputSamples; //qDebug() << "pushing " << numNetworkOutputSamples;
_ringBuffer.setIsStarved(false); _ringBuffer.setIsStarved(false);

View file

@ -575,6 +575,8 @@ Menu::Menu() :
Qt::CTRL | Qt::SHIFT | Qt::Key_U, Qt::CTRL | Qt::SHIFT | Qt::Key_U,
false); false);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::DisableQAudioOutputOverflowCheck, 0, false);
addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,
Qt::CTRL | Qt::SHIFT | Qt::Key_V, Qt::CTRL | Qt::SHIFT | Qt::Key_V,
this, this,

View file

@ -343,6 +343,7 @@ namespace MenuOption {
const QString DecreaseVoxelSize = "Decrease Voxel Size"; const QString DecreaseVoxelSize = "Decrease Voxel Size";
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD"; const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
const QString DisableNackPackets = "Disable NACK Packets"; const QString DisableNackPackets = "Disable NACK Packets";
const QString DisableQAudioOutputOverflowCheck = "Disable QAudioOutput Overflow Check";
const QString DisplayFrustum = "Display Frustum"; const QString DisplayFrustum = "Display Frustum";
const QString DisplayHands = "Display Hands"; const QString DisplayHands = "Display Hands";
const QString DisplayHandTargets = "Display Hand Targets"; const QString DisplayHandTargets = "Display Hand Targets";

View file

@ -99,7 +99,8 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
_listenerUnattenuatedZone(NULL), _listenerUnattenuatedZone(NULL),
_desiredJitterBufferFrames(1), _desiredJitterBufferFrames(1),
_currentJitterBufferFrames(-1), _currentJitterBufferFrames(-1),
_dynamicJitterBuffers(dynamicJitterBuffers) _dynamicJitterBuffers(dynamicJitterBuffers),
_consecutiveNotMixedCount(0)
{ {
} }
@ -129,7 +130,7 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
numSilentSamples = getSamplesPerFrame(); numSilentSamples = getSamplesPerFrame();
if (numSilentSamples > 0) { if (numSilentSamples > 0) {
if (_currentJitterBufferFrames > _desiredJitterBufferFrames) { if (_dynamicJitterBuffers && _currentJitterBufferFrames > _desiredJitterBufferFrames) {
// our current jitter buffer size exceeds its desired value, so ignore some silent // our current jitter buffer size exceeds its desired value, so ignore some silent
// frames to get that size as close to desired as possible // frames to get that size as close to desired as possible
int samplesPerFrame = getSamplesPerFrame(); int samplesPerFrame = getSamplesPerFrame();
@ -206,11 +207,12 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
if (!isNotStarvedOrHasMinimumSamples(samplesPerFrame + desiredJitterBufferSamples)) { if (!isNotStarvedOrHasMinimumSamples(samplesPerFrame + desiredJitterBufferSamples)) {
// if the buffer was starved, allow it to accrue at least the desired number of // if the buffer was starved, allow it to accrue at least the desired number of
// jitter buffer frames before we start taking frames from it for mixing // jitter buffer frames before we start taking frames from it for mixing
if (_shouldOutputStarveDebug) { if (_shouldOutputStarveDebug) {
_shouldOutputStarveDebug = false; _shouldOutputStarveDebug = false;
} }
_consecutiveNotMixedCount++;
return false; return false;
} else if (samplesAvailable() < samplesPerFrame) { } else if (samplesAvailable() < samplesPerFrame) {
// if the buffer doesn't have a full frame of samples to take for mixing, it is starved // if the buffer doesn't have a full frame of samples to take for mixing, it is starved
@ -222,6 +224,7 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
// reset our _shouldOutputStarveDebug to true so the next is printed // reset our _shouldOutputStarveDebug to true so the next is printed
_shouldOutputStarveDebug = true; _shouldOutputStarveDebug = true;
_consecutiveNotMixedCount++;
return false; return false;
} }
@ -231,6 +234,7 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
// minus one (since a frame will be read immediately after this) is the length of the jitter buffer // minus one (since a frame will be read immediately after this) is the length of the jitter buffer
_currentJitterBufferFrames = samplesAvailable() / samplesPerFrame - 1; _currentJitterBufferFrames = samplesAvailable() / samplesPerFrame - 1;
_isStarved = false; _isStarved = false;
_consecutiveNotMixedCount = 0;
} }
// since we've read data from ring buffer at least once - we've started // since we've read data from ring buffer at least once - we've started

View file

@ -83,6 +83,8 @@ public:
int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; } int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; }
int getCurrentJitterBufferFrames() const { return _currentJitterBufferFrames; } int getCurrentJitterBufferFrames() const { return _currentJitterBufferFrames; }
int getConsecutiveNotMixedCount() const { return _consecutiveNotMixedCount; }
protected: protected:
// disallow copying of PositionalAudioRingBuffer objects // disallow copying of PositionalAudioRingBuffer objects
PositionalAudioRingBuffer(const PositionalAudioRingBuffer&); PositionalAudioRingBuffer(const PositionalAudioRingBuffer&);
@ -107,9 +109,7 @@ protected:
bool _dynamicJitterBuffers; bool _dynamicJitterBuffers;
// extra stats // extra stats
int _starveCount; int _consecutiveNotMixedCount;
int _silentFramesDropped;
}; };
#endif // hifi_PositionalAudioRingBuffer_h #endif // hifi_PositionalAudioRingBuffer_h

View file

@ -515,8 +515,6 @@ void ScriptEngine::run() {
qint64 now = usecTimestampNow(); qint64 now = usecTimestampNow();
float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND; float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;
emit update(deltaTime);
lastUpdate = now;
if (_engine.hasUncaughtException()) { if (_engine.hasUncaughtException()) {
int line = _engine.uncaughtExceptionLineNumber(); int line = _engine.uncaughtExceptionLineNumber();
@ -524,6 +522,9 @@ void ScriptEngine::run() {
emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + _engine.uncaughtException().toString()); emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + _engine.uncaughtException().toString());
_engine.clearExceptions(); _engine.clearExceptions();
} }
emit update(deltaTime);
lastUpdate = now;
} }
emit scriptEnding(); emit scriptEnding();