first cut at selecting audio sources

This commit is contained in:
ZappoMan 2013-07-22 13:54:47 -07:00
parent dc19a1c5cf
commit c301b799c5
8 changed files with 171 additions and 5 deletions

View file

@ -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;

View file

@ -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__) */

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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);