have the AudioMixer handle silent audio, send silence from Interface when gate closed

This commit is contained in:
Stephen Birarda 2014-03-17 15:12:02 -07:00
parent c7e12824a8
commit 9f24bd9c47
5 changed files with 67 additions and 13 deletions

View file

@ -436,9 +436,8 @@ void Audio::handleAudioInput() {
}
}
if (!_noiseGateOpen) {
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
monoAudioSamples[i] = 0;
}
memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
_lastInputLoudness = 0;
}
}
@ -482,9 +481,26 @@ void Audio::handleAudioInput() {
// we need the amount of bytes in the buffer + 1 for type
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
PacketType packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
? PacketTypeMicrophoneAudioWithEcho : PacketTypeMicrophoneAudioNoEcho;
int numAudioBytes = 0;
PacketType packetType;
if (_lastInputLoudness == 0) {
packetType = PacketTypeSilentAudioListener;
// we need to indicate how many silent samples this is to the audio mixer
monoAudioSamples[0] = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
numAudioBytes = sizeof(int16_t);
} else {
numAudioBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL;
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)) {
packetType = PacketTypeMicrophoneAudioWithEcho;
} else {
packetType = PacketTypeMicrophoneAudioNoEcho;
}
}
char* currentPacketPtr = monoAudioDataPacket + populatePacketHeader(monoAudioDataPacket, packetType);
@ -495,10 +511,8 @@ void Audio::handleAudioInput() {
// memcpy our orientation
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
currentPacketPtr += sizeof(headOrientation);
nodeList->writeDatagram(monoAudioDataPacket,
NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes,
audioMixer);
nodeList->writeDatagram(monoAudioDataPacket, numAudioBytes + leadingBytes, audioMixer);
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
.updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
@ -638,7 +652,14 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) {
int16_t collisionSample = (int16_t) sample;
_lastInputLoudness = 0;
monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
_lastInputLoudness += fabsf(monoInput[i]);
_lastInputLoudness /= numSamples;
_lastInputLoudness /= MAX_SAMPLE_VALUE;
_localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample,
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
@ -662,7 +683,14 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) {
int16_t collisionSample = (int16_t) sample;
_lastInputLoudness = 0;
monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
_lastInputLoudness += fabsf(monoInput[i]);
_lastInputLoudness /= numSamples;
_lastInputLoudness /= MAX_SAMPLE_VALUE;
_localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample,
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);

View file

@ -156,6 +156,19 @@ unsigned int AudioRingBuffer::samplesAvailable() const {
}
}
void AudioRingBuffer::addSilentFrame(int numSilentSamples) {
// setup the silent frame
int numSilentBytes = numSilentSamples * sizeof(int16_t);
char* silentFrame = new char[numSilentBytes];
memset(silentFrame, 0, numSilentBytes);
// write it
writeData(silentFrame, numSilentBytes);
// delete the temporary silent frame
delete[] silentFrame;
}
bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const {
if (!_isStarved) {
return true;

View file

@ -70,6 +70,8 @@ public:
void setIsStarved(bool isStarved) { _isStarved = isStarved; }
bool hasStarted() const { return _hasStarted; }
void addSilentFrame(int numSilentSamples);
protected:
// disallow copying of AudioRingBuffer objects
AudioRingBuffer(const AudioRingBuffer&);

View file

@ -44,8 +44,19 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
packetStream.skipRawData(numBytesForPacketHeader(packet));
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
packet.size() - packetStream.device()->pos()));
if (packetTypeForPacket(packet) == PacketTypeSilentAudioListener) {
// this source had no audio to send us, but this counts as a packet
// write silence equivalent to the number of silent samples they just sent us
int16_t numSilentSamples;
packetStream >> numSilentSamples;
addSilentFrame(numSilentSamples);
} else {
// there is audio data to read
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
packet.size() - packetStream.device()->pos()));
}
return packetStream.device()->pos();
}

View file

@ -32,7 +32,7 @@ enum PacketType {
PacketTypeMicrophoneAudioNoEcho,
PacketTypeMicrophoneAudioWithEcho,
PacketTypeBulkAvatarData,
PacketTypeTransmitterData, // usable
PacketTypeSilentAudioListener,
PacketTypeEnvironmentData,
PacketTypeDomainListRequest,
PacketTypeRequestAssignment,