mirror of
https://github.com/overte-org/overte.git
synced 2025-08-12 04:29:02 +02:00
first cut at selecting audio sources
This commit is contained in:
parent
dc19a1c5cf
commit
c301b799c5
8 changed files with 171 additions and 5 deletions
|
@ -16,19 +16,66 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer() :
|
|||
AudioRingBuffer(false),
|
||||
_position(0.0f, 0.0f, 0.0f),
|
||||
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
_willBeAddedToMix(false)
|
||||
_willBeAddedToMix(false),
|
||||
_sourceID(-1),
|
||||
_listenMode(AudioRingBuffer::NORMAL),
|
||||
_listenRadius(0.0f),
|
||||
_listenSourceCount(0),
|
||||
_listenSources(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PositionalAudioRingBuffer::~PositionalAudioRingBuffer() {
|
||||
if (_listenSources) {
|
||||
delete[] _listenSources;
|
||||
}
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
|
||||
currentBuffer += parseSourceData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
currentBuffer += parseListenModeData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
currentBuffer += parseAudioSamples(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parseSourceData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer;
|
||||
|
||||
memcpy(&_sourceID, currentBuffer, sizeof(_sourceID));
|
||||
currentBuffer += sizeof(_sourceID);
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parseListenModeData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer;
|
||||
|
||||
memcpy(&_listenMode, currentBuffer, sizeof(_listenMode));
|
||||
currentBuffer += sizeof(_listenMode);
|
||||
|
||||
if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) {
|
||||
memcpy(&_listenRadius, currentBuffer, sizeof(_listenRadius));
|
||||
currentBuffer += sizeof(_listenRadius);
|
||||
} else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) {
|
||||
memcpy(&_listenSourceCount, currentBuffer, sizeof(_listenSourceCount));
|
||||
currentBuffer += sizeof(_listenSourceCount);
|
||||
|
||||
if (_listenSources) {
|
||||
delete[] _listenSources;
|
||||
}
|
||||
_listenSources = new int[_listenSourceCount];
|
||||
memcpy(_listenSources, currentBuffer, sizeof(int) * _listenSourceCount);
|
||||
currentBuffer += sizeof(int) * _listenSourceCount;
|
||||
|
||||
}
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer;
|
||||
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
class PositionalAudioRingBuffer : public AudioRingBuffer {
|
||||
public:
|
||||
PositionalAudioRingBuffer();
|
||||
~PositionalAudioRingBuffer();
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parsePositionalData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseSourceData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseListenModeData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
bool shouldBeAddedToMix(int numJitterBufferSamples);
|
||||
|
||||
|
@ -36,6 +39,13 @@ protected:
|
|||
glm::vec3 _position;
|
||||
glm::quat _orientation;
|
||||
bool _willBeAddedToMix;
|
||||
|
||||
int _sourceID;
|
||||
int _listenMode;
|
||||
float _listenRadius;
|
||||
int _listenSourceCount;
|
||||
int* _listenSources;
|
||||
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__PositionalAudioRingBuffer__) */
|
||||
|
|
|
@ -3447,9 +3447,19 @@ void* Application::networkReceive(void* args) {
|
|||
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
||||
processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
default:
|
||||
default: {
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived);
|
||||
|
||||
// Check to see if we have our ownerID
|
||||
uint16_t ownerID = NodeList::getInstance()->getOwnerID();
|
||||
|
||||
if (ownerID != app->_audio.getSourceID()) {
|
||||
app->_audio.setSourceID(ownerID);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!app->_enableNetworkThread) {
|
||||
|
|
|
@ -120,6 +120,27 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
|
|||
|
||||
unsigned char* currentPacketPtr = dataPacket + populateTypeAndVersion(dataPacket, packetType);
|
||||
|
||||
// pack Source Data
|
||||
memcpy(currentPacketPtr, &_sourceID, sizeof(_sourceID));
|
||||
currentPacketPtr += (sizeof(_sourceID));
|
||||
|
||||
// pack Listen Mode Data
|
||||
memcpy(currentPacketPtr, &_listenMode, sizeof(_listenMode));
|
||||
currentPacketPtr += (sizeof(_listenMode));
|
||||
|
||||
if (_listenMode == AudioRingBuffer::OMNI_DIRECTIONAL_POINT) {
|
||||
memcpy(currentPacketPtr, &_listenRadius, sizeof(_listenRadius));
|
||||
currentPacketPtr += (sizeof(_listenRadius));
|
||||
} else if (_listenMode == AudioRingBuffer::SELECTED_SOURCES) {
|
||||
memcpy(currentPacketPtr, &_listenSourceCount, sizeof(_listenSourceCount));
|
||||
currentPacketPtr += (sizeof(_listenSourceCount));
|
||||
|
||||
if (_listenSources) {
|
||||
memcpy(currentPacketPtr, &_listenSources, sizeof(int) * _listenSourceCount);
|
||||
currentPacketPtr += (sizeof(int) * _listenSourceCount);
|
||||
}
|
||||
}
|
||||
|
||||
// memcpy the three float positions
|
||||
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
|
||||
currentPacketPtr += (sizeof(headPosition));
|
||||
|
@ -309,6 +330,49 @@ void Audio::reset() {
|
|||
_ringBuffer.reset();
|
||||
}
|
||||
|
||||
void Audio::addListenSource(int sourceID) {
|
||||
|
||||
// If we don't yet have a list of listen sources, make one
|
||||
if (!_listenSources) {
|
||||
_listenSources = new int[AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE];
|
||||
}
|
||||
|
||||
// First check to see if the source is already in our list
|
||||
for (int i = 0; i < _listenSourceCount; i++) {
|
||||
if (_listenSources[i] == sourceID) {
|
||||
return; // already in list
|
||||
}
|
||||
}
|
||||
|
||||
// we know it's not in the list, check to see if we have room to add our source
|
||||
if (_listenSourceCount + 1 < _listenSourcesArraySize) {
|
||||
int* newList = new int[_listenSourcesArraySize + AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE];
|
||||
memmove(newList, _listenSources, _listenSourcesArraySize);
|
||||
delete[] _listenSources;
|
||||
_listenSources = newList;
|
||||
_listenSourcesArraySize += AudioRingBuffer::DEFAULT_LISTEN_LIST_SIZE;
|
||||
}
|
||||
_listenSources[_listenSourceCount] = sourceID;
|
||||
_listenSourceCount++;
|
||||
}
|
||||
|
||||
void Audio::removeListenSource(int sourceID) {
|
||||
// If we don't yet have a list of listen sources, make one
|
||||
if (_listenSources) {
|
||||
// First check to see if the source is already in our list
|
||||
for (int i = 0; i < _listenSourceCount; i++) {
|
||||
if (_listenSources[i] == sourceID) {
|
||||
|
||||
// found it, so, move the items forward in list
|
||||
memmove(&_listenSources[i], &_listenSources[i+1], _listenSourceCount - i);
|
||||
_listenSourceCount--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
||||
_stream(NULL),
|
||||
_ringBuffer(true),
|
||||
|
@ -338,7 +402,13 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) :
|
|||
_collisionSoundNoise(0.0f),
|
||||
_collisionSoundDuration(0.0f),
|
||||
_proceduralEffectSample(0),
|
||||
_heartbeatMagnitude(0.0f)
|
||||
_heartbeatMagnitude(0.0f),
|
||||
_sourceID(UNKNOWN_NODE_ID),
|
||||
_listenMode(AudioRingBuffer::NORMAL),
|
||||
_listenRadius(0.0f),
|
||||
_listenSourceCount(0),
|
||||
_listenSourcesArraySize(0),
|
||||
_listenSources(NULL)
|
||||
{
|
||||
outputPortAudioError(Pa_Initialize());
|
||||
|
||||
|
@ -407,6 +477,10 @@ Audio::~Audio() {
|
|||
outputPortAudioError(Pa_Terminate());
|
||||
}
|
||||
delete[] _echoSamplesLeft;
|
||||
|
||||
if (_listenSources) {
|
||||
delete[] _listenSources;
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) {
|
||||
|
|
|
@ -54,6 +54,12 @@ public:
|
|||
// The results of the analysis are written to the log.
|
||||
bool eventuallyAnalyzePing();
|
||||
|
||||
int getSourceID() const { return _sourceID; };
|
||||
void setSourceID(int sourceID) { _sourceID = sourceID; };
|
||||
void setListenMode(int mode) { _listenMode = mode; };
|
||||
void setListenRadius(float radius) { _listenRadius = radius; };
|
||||
void addListenSource(int sourceID);
|
||||
void removeListenSource(int sourceID);
|
||||
|
||||
private:
|
||||
PaStream* _stream;
|
||||
|
@ -90,6 +96,13 @@ private:
|
|||
float _collisionSoundDuration;
|
||||
int _proceduralEffectSample;
|
||||
float _heartbeatMagnitude;
|
||||
|
||||
int _sourceID;
|
||||
int _listenMode;
|
||||
float _listenRadius;
|
||||
int _listenSourceCount;
|
||||
int _listenSourcesArraySize;
|
||||
int* _listenSources;
|
||||
|
||||
// Audio callback in class context.
|
||||
inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight);
|
||||
|
|
|
@ -27,6 +27,14 @@ const short RING_BUFFER_LENGTH_SAMPLES = RING_BUFFER_LENGTH_FRAMES * BUFFER_LENG
|
|||
|
||||
class AudioRingBuffer : public NodeData {
|
||||
public:
|
||||
|
||||
static int const DEFAULT_LISTEN_LIST_SIZE = 100;
|
||||
enum {
|
||||
NORMAL,
|
||||
OMNI_DIRECTIONAL_POINT,
|
||||
SELECTED_SOURCES
|
||||
};
|
||||
|
||||
AudioRingBuffer(bool isStereo);
|
||||
~AudioRingBuffer();
|
||||
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
|
||||
PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
||||
switch (type) {
|
||||
|
||||
case PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO:
|
||||
case PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case PACKET_TYPE_HEAD_DATA:
|
||||
return 2;
|
||||
break;
|
||||
|
|
|
@ -35,8 +35,6 @@ const PACKET_TYPE PACKET_TYPE_ENVIRONMENT_DATA = 'e';
|
|||
const PACKET_TYPE PACKET_TYPE_DOMAIN_LIST_REQUEST = 'L';
|
||||
const PACKET_TYPE PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY = 'C';
|
||||
|
||||
// this is a test...
|
||||
|
||||
typedef char PACKET_VERSION;
|
||||
|
||||
PACKET_VERSION versionForPacketType(PACKET_TYPE type);
|
||||
|
|
Loading…
Reference in a new issue