History

allow Agents to microphone audio from Sound objects

Stephen Birarda committed 12 years ago

Commit 8c4fad41 parent 08c5c494 files · +67 −53Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+50−15
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <QtNetwork/QNetworkRequest>14#include <QtNetwork/QNetworkRequest>
15#include <QtNetwork/QNetworkReply>15#include <QtNetwork/QNetworkReply>
16 16
17#include <AudioRingBuffer.h>
17#include <AvatarData.h>18#include <AvatarData.h>
18#include <NodeList.h>19#include <NodeList.h>
19#include <PacketHeaders.h>20#include <PacketHeaders.h>
@@ -52,7 +53,9 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co · 32 unmodified lines
52 _avatarIdentityTimer(NULL),53 _avatarIdentityTimer(NULL),
53 _avatarBillboardTimer(NULL),54 _avatarBillboardTimer(NULL),
54 _timerFunctionMap(),55 _timerFunctionMap(),
55 _avatarAudioBuffer(NULL),56 _isListeningToAudioStream(false),
57 _avatarSound(NULL),
58 _numAvatarSoundSentBytes(0),
56 _controllerScriptingInterface(controllerScriptingInterface),59 _controllerScriptingInterface(controllerScriptingInterface),
57 _avatarData(NULL),60 _avatarData(NULL),
58 _wantMenuItems(wantMenuItems),61 _wantMenuItems(wantMenuItems),
@@ -260,27 +263,55 @@ void ScriptEngine::run() { · 201 unmodified lines
260 }263 }
261 264
262 if (_isAvatar && _avatarData) {265 if (_isAvatar && _avatarData) {
266
267 const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * SAMPLE_RATE) / (1000 * 1000)) + 0.5);
268 const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
269
263 QByteArray avatarPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);270 QByteArray avatarPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
264 avatarPacket.append(_avatarData->toByteArray());271 avatarPacket.append(_avatarData->toByteArray());
265 272
266 nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);273 nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
267 274
268 if (_avatarAudioBuffer && _numAvatarAudioBufferSamples > 0) {275 if (_isListeningToAudioStream || _avatarSound) {
269 // if have an avatar audio stream then send it out to our audio-mixer276 // if we have an avatar audio stream then send it out to our audio-mixer
270
271 bool silentFrame = true;277 bool silentFrame = true;
272 278
273 // check if the all of the _numAvatarAudioBufferSamples to be sent are silence279 int16_t numAvailableSamples = SCRIPT_AUDIO_BUFFER_SAMPLES;
274 for (int i = 0; i < _numAvatarAudioBufferSamples; ++i) {280 const int16_t* nextSoundOutput = NULL;
275 if (_avatarAudioBuffer[i] != 0) {281
276 silentFrame = false;282 if (_avatarSound) {
277 break;283
284 const QByteArray& soundByteArray = _avatarSound->getByteArray();
285 nextSoundOutput = reinterpret_cast<const int16_t*>(soundByteArray.data()
286 + _numAvatarSoundSentBytes);
287
288 int numAvailableBytes = (soundByteArray.size() - _numAvatarSoundSentBytes) > SCRIPT_AUDIO_BUFFER_BYTES
289 ? SCRIPT_AUDIO_BUFFER_BYTES
290 : soundByteArray.size() - _numAvatarSoundSentBytes;
291 numAvailableSamples = numAvailableBytes / sizeof(int16_t);
292
293
294 // check if the all of the _numAvatarAudioBufferSamples to be sent are silence
295 for (int i = 0; i < numAvailableSamples; ++i) {
296 if (nextSoundOutput[i] != 0) {
297 silentFrame = false;
298 break;
299 }
300 }
301
302 _numAvatarSoundSentBytes += numAvailableBytes;
303 if (_numAvatarSoundSentBytes == soundByteArray.size()) {
304 // we're done with this sound object - so set our pointer back to NULL
305 // and our sent bytes back to zero
306 _avatarSound = NULL;
307 _numAvatarSoundSentBytes = 0;
278 }308 }
279 }309 }
280 310
281 QByteArray audioPacket = byteArrayWithPopulatedHeader(silentFrame311 QByteArray audioPacket = byteArrayWithPopulatedHeader(silentFrame
282 ? PacketTypeSilentAudioFrame312 ? PacketTypeSilentAudioFrame
283 : PacketTypeMicrophoneAudioNoEcho);313 : PacketTypeMicrophoneAudioNoEcho);
314
284 QDataStream packetStream(&audioPacket, QIODevice::Append);315 QDataStream packetStream(&audioPacket, QIODevice::Append);
285 316
286 // use the orientation and position of this avatar for the source of this audio317 // use the orientation and position of this avatar for the source of this audio
@@ -289,13 +320,17 @@ void ScriptEngine::run() { · 2 unmodified lines
289 packetStream.writeRawData(reinterpret_cast<const char*>(&headOrientation), sizeof(glm::quat));320 packetStream.writeRawData(reinterpret_cast<const char*>(&headOrientation), sizeof(glm::quat));
290 321
291 if (silentFrame) {322 if (silentFrame) {
323 if (!_isListeningToAudioStream) {
324 // if we have a silent frame and we're not listening then just send nothing and break out of here
325 break;
326 }
327
292 // write the number of silent samples so the audio-mixer can uphold timing328 // write the number of silent samples so the audio-mixer can uphold timing
293 int16_t numSilentSamples = _numAvatarAudioBufferSamples;329 packetStream.writeRawData(reinterpret_cast<const char*>(&SCRIPT_AUDIO_BUFFER_SAMPLES), sizeof(int16_t));
294 packetStream.writeRawData(reinterpret_cast<const char*>(&numSilentSamples), sizeof(int16_t));330 } else if (nextSoundOutput) {
295 } else {
296 // write the raw audio data331 // write the raw audio data
297 packetStream.writeRawData(reinterpret_cast<const char*>(_avatarAudioBuffer),332 packetStream.writeRawData(reinterpret_cast<const char*>(nextSoundOutput),
298 _numAvatarAudioBufferSamples * sizeof(int16_t));333 numAvailableSamples * sizeof(int16_t));
299 }334 }
300 335
301 nodeList->broadcastToNodes(audioPacket, NodeSet() << NodeType::AudioMixer);336 nodeList->broadcastToNodes(audioPacket, NodeSet() << NodeType::AudioMixer);
@@ -303,7 +338,7 @@ void ScriptEngine::run() { · 1 unmodified line
303 }338 }
304 339
305 qint64 now = usecTimestampNow();340 qint64 now = usecTimestampNow();
306 float deltaTime = (float)(now - lastUpdate)/(float)USECS_PER_SECOND;341 float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;
307 emit update(deltaTime);342 emit update(deltaTime);
308 lastUpdate = now;343 lastUpdate = now;
309 344