mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 20:31:29 +02:00
have the AudioMixer handle silent audio, send silence from Interface when gate closed
This commit is contained in:
parent
c7e12824a8
commit
9f24bd9c47
5 changed files with 67 additions and 13 deletions
|
@ -436,9 +436,8 @@ void Audio::handleAudioInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_noiseGateOpen) {
|
if (!_noiseGateOpen) {
|
||||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
monoAudioSamples[i] = 0;
|
_lastInputLoudness = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,9 +481,26 @@ void Audio::handleAudioInput() {
|
||||||
|
|
||||||
// we need the amount of bytes in the buffer + 1 for type
|
// we need the amount of bytes in the buffer + 1 for type
|
||||||
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
||||||
|
|
||||||
PacketType packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
|
int numAudioBytes = 0;
|
||||||
? PacketTypeMicrophoneAudioWithEcho : PacketTypeMicrophoneAudioNoEcho;
|
|
||||||
|
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);
|
char* currentPacketPtr = monoAudioDataPacket + populatePacketHeader(monoAudioDataPacket, packetType);
|
||||||
|
|
||||||
|
@ -495,10 +511,8 @@ void Audio::handleAudioInput() {
|
||||||
// memcpy our orientation
|
// memcpy our orientation
|
||||||
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
|
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
|
||||||
currentPacketPtr += sizeof(headOrientation);
|
currentPacketPtr += sizeof(headOrientation);
|
||||||
|
|
||||||
nodeList->writeDatagram(monoAudioDataPacket,
|
nodeList->writeDatagram(monoAudioDataPacket, numAudioBytes + leadingBytes, audioMixer);
|
||||||
NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes,
|
|
||||||
audioMixer);
|
|
||||||
|
|
||||||
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
|
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO)
|
||||||
.updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
|
.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;
|
int16_t collisionSample = (int16_t) sample;
|
||||||
|
|
||||||
|
_lastInputLoudness = 0;
|
||||||
|
|
||||||
monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
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,
|
_localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample,
|
||||||
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
||||||
|
|
||||||
|
@ -662,7 +683,14 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) {
|
||||||
|
|
||||||
int16_t collisionSample = (int16_t) sample;
|
int16_t collisionSample = (int16_t) sample;
|
||||||
|
|
||||||
|
_lastInputLoudness = 0;
|
||||||
|
|
||||||
monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
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,
|
_localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample,
|
||||||
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const {
|
||||||
if (!_isStarved) {
|
if (!_isStarved) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -70,6 +70,8 @@ public:
|
||||||
void setIsStarved(bool isStarved) { _isStarved = isStarved; }
|
void setIsStarved(bool isStarved) { _isStarved = isStarved; }
|
||||||
|
|
||||||
bool hasStarted() const { return _hasStarted; }
|
bool hasStarted() const { return _hasStarted; }
|
||||||
|
|
||||||
|
void addSilentFrame(int numSilentSamples);
|
||||||
protected:
|
protected:
|
||||||
// disallow copying of AudioRingBuffer objects
|
// disallow copying of AudioRingBuffer objects
|
||||||
AudioRingBuffer(const AudioRingBuffer&);
|
AudioRingBuffer(const AudioRingBuffer&);
|
||||||
|
|
|
@ -44,8 +44,19 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||||
|
|
||||||
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
|
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();
|
return packetStream.device()->pos();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ enum PacketType {
|
||||||
PacketTypeMicrophoneAudioNoEcho,
|
PacketTypeMicrophoneAudioNoEcho,
|
||||||
PacketTypeMicrophoneAudioWithEcho,
|
PacketTypeMicrophoneAudioWithEcho,
|
||||||
PacketTypeBulkAvatarData,
|
PacketTypeBulkAvatarData,
|
||||||
PacketTypeTransmitterData, // usable
|
PacketTypeSilentAudioListener,
|
||||||
PacketTypeEnvironmentData,
|
PacketTypeEnvironmentData,
|
||||||
PacketTypeDomainListRequest,
|
PacketTypeDomainListRequest,
|
||||||
PacketTypeRequestAssignment,
|
PacketTypeRequestAssignment,
|
||||||
|
|
Loading…
Reference in a new issue