void ProcessSpatializationForVoice(ESpatializationEffectType Type, uint32 VoiceIndex, float* InSamples, float* OutSamples, const FVector& Position) override { if (Type == SPATIALIZATION_TYPE_FAST) { ProcessAudio(OvrAudioContextFast, VoiceIndex, InSamples, OutSamples, Position); } #if OCULUS_HQ_ENABLED else { check(Type == SPATIALIZATION_TYPE_HIGH_QUALITY); ProcessAudio(OvrAudioContextHighQuality, VoiceIndex, InSamples, OutSamples, Position); } #endif // #if OCULUS_HQ_ENABLED }
int CALSAAudioSource::ThreadMain(void) { debug_message("alsa start"); while (true) { int rc; if (m_source) { rc = SDL_SemTryWait(m_myMsgQueueSemaphore); } else { rc = SDL_SemWait(m_myMsgQueueSemaphore); } // semaphore error if (rc == -1) { break; } // message pending if (rc == 0) { CMsg* pMsg = m_myMsgQueue.get_message(); if (pMsg != NULL) { switch (pMsg->get_value()) { case MSG_NODE_STOP_THREAD: DoStopCapture(); // ensure things get cleaned up delete pMsg; debug_message("alsa stop thread"); return 0; case MSG_NODE_START: DoStartCapture(); break; case MSG_NODE_STOP: DoStopCapture(); break; } delete pMsg; } } if (m_source) { try { //debug_message("processaudio"); ProcessAudio(); } catch (...) { error_message("alsa stop capture"); DoStopCapture(); break; } } } debug_message("alsa thread exit"); return -1; }
int COSSAudioSource::ThreadMain(void) { while (true) { int rc; if (m_source) { rc = SDL_SemTryWait(m_myMsgQueueSemaphore); } else { rc = SDL_SemWait(m_myMsgQueueSemaphore); } // semaphore error if (rc == -1) { break; } // message pending if (rc == 0) { CMsg* pMsg = m_myMsgQueue.get_message(); if (pMsg != NULL) { switch (pMsg->get_value()) { case MSG_NODE_STOP_THREAD: DoStopCapture(); // ensure things get cleaned up delete pMsg; return 0; case MSG_NODE_START: case MSG_SOURCE_START_AUDIO: DoStartCapture(); break; case MSG_NODE_STOP: DoStopCapture(); break; } delete pMsg; } } if (m_source) { try { ProcessAudio(); } catch (...) { DoStopCapture(); break; } } } return -1; }
bool MythRAOPConnection::Init(void) { // connect up the request socket m_textStream = new NetStream(m_socket); m_textStream->setCodec("UTF-8"); if (!connect(m_socket, SIGNAL(readyRead()), this, SLOT(readClient()))) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect client socket signal."); return false; } // create the data socket m_dataSocket = new ServerPool(); if (!connect(m_dataSocket, SIGNAL(newDatagram(QByteArray, QHostAddress, quint16)), this, SLOT(udpDataReady(QByteArray, QHostAddress, quint16)))) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect data socket signal."); return false; } // try a few ports in case the first is in use m_dataPort = m_dataSocket->tryBindingPort(m_dataPort, RAOP_PORT_RANGE); if (m_dataPort < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to bind to a port for data."); return false; } LOG(VB_GENERAL, LOG_INFO, LOC + QString("Bound to port %1 for incoming data").arg(m_dataPort)); // load the private key if (!LoadKey()) return false; // use internal volume control m_allowVolumeControl = gCoreContext->GetNumSetting("MythControlsVolume", 1); // start the watchdog timer to auto delete the client after a period of inactivity m_watchdogTimer = new QTimer(); connect(m_watchdogTimer, SIGNAL(timeout()), this, SLOT(timeout())); m_watchdogTimer->start(10000); m_dequeueAudioTimer = new QTimer(); connect(m_dequeueAudioTimer, SIGNAL(timeout()), this, SLOT(ProcessAudio())); return true; }
int CAudioDecoder::ReadSamples(int numsamples) { if (m_status == STATUS_NO_FILE || m_status == STATUS_ENDING || m_status == STATUS_ENDED) return RET_SLEEP; // nothing loaded yet // start playing once we're fully queued and we're ready to go if (m_status == STATUS_QUEUED && m_canPlay) m_status = STATUS_PLAYING; // grab a lock to ensure the codec is created at this point. CSingleLock lock(m_critSection); // Read in more data int maxsize = std::min<int>(INPUT_SAMPLES, (m_pcmBuffer.getMaxWriteSize() / (int)(sizeof (float)))); numsamples = std::min<int>(numsamples, maxsize); numsamples -= (numsamples % m_codec->m_Channels); // make sure it's divisible by our number of channels if ( numsamples ) { int actualsamples = 0; // if our codec sends floating point, then read it int result = READ_ERROR; if (m_codec->HasFloatData()) result = m_codec->ReadSamples(m_inputBuffer, numsamples, &actualsamples); else result = ReadPCMSamples(m_inputBuffer, numsamples, &actualsamples); if ( result != READ_ERROR && actualsamples ) { // do any post processing of the audio (eg replaygain etc.) ProcessAudio(m_inputBuffer, actualsamples); // move it into our buffer m_pcmBuffer.WriteData((char *)m_inputBuffer, actualsamples * sizeof(float)); // update status if (m_status == STATUS_QUEUING && m_pcmBuffer.getMaxReadSize() > m_pcmBuffer.getSize() * 0.9) { CLog::Log(LOGINFO, "AudioDecoder: File is queued"); m_status = STATUS_QUEUED; } if (result == READ_EOF) // EOF reached { // setup ending if we're within set time of the end (currently just EOF) m_eof = true; if (m_status < STATUS_ENDING) m_status = STATUS_ENDING; } return RET_SUCCESS; } if (result == READ_ERROR) { // error decoding, lets finish up and get out CLog::Log(LOGERROR, "CAudioDecoder: Error while decoding %i", result); return RET_ERROR; } if (result == READ_EOF) { m_eof = true; // setup ending if we're within set time of the end (currently just EOF) if (m_status < STATUS_ENDING) m_status = STATUS_ENDING; } } return RET_SLEEP; // nothing to do }
/** * Socket incoming data signal handler * use for audio, control and timing socket */ void MythRAOPConnection::udpDataReady(QByteArray buf, QHostAddress peer, quint16 port) { // restart the idle timer if (m_watchdogTimer) m_watchdogTimer->start(10000); if (!m_audio || !m_codec || !m_codeccontext) return; uint8_t type; uint16_t seq; uint64_t timestamp; if (!GetPacketType(buf, type, seq, timestamp)) { LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Packet doesn't start with valid Rtp Header (0x%1)") .arg((uint8_t)buf[0], 0, 16)); return; } switch (type) { case SYNC: case FIRSTSYNC: ProcessSync(buf); ProcessAudio(); return; case FIRSTAUDIO_DATA: m_nextSequence = seq; m_nextTimestamp = timestamp; // With iTunes we know what the first sequence is going to be. // iOS device do not tell us before streaming start what the first // packet is going to be. m_streamingStarted = true; break; case AUDIO_DATA: case AUDIO_RESEND: break; case TIMING_RESPONSE: ProcessTimeResponse(buf); return; default: LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Packet type (0x%1) not handled") .arg(type, 0, 16)); return; } timestamp = framesToMs(timestamp); if (timestamp < m_currentTimestamp) { LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Received packet %1 too late, ignoring") .arg(seq)); return; } // regular data packet if (type == AUDIO_DATA || type == FIRSTAUDIO_DATA) { if (m_streamingStarted && seq != m_nextSequence) SendResendRequest(timestamp, m_nextSequence, seq); m_nextSequence = seq + 1; m_nextTimestamp = timestamp; m_streamingStarted = true; } if (!m_streamingStarted) return; // resent packet if (type == AUDIO_RESEND) { if (m_resends.contains(seq)) { LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Received required resend %1 (with ts:%2 last:%3)") .arg(seq).arg(timestamp).arg(m_nextSequence)); m_resends.remove(seq); } else LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Received unexpected resent packet %1") .arg(seq)); } // Check that the audio packet is valid, do so by decoding it. If an error // occurs, ask to resend it QList<AudioData> *decoded = new QList<AudioData>(); int numframes = decodeAudioPacket(type, &buf, decoded); if (numframes < 0) { // an error occurred, ask for the audio packet once again. LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error decoding audio")); SendResendRequest(timestamp, seq, seq+1); return; } AudioPacket frames; frames.seq = seq; frames.data = decoded; m_audioQueue.insert(timestamp, frames); ProcessAudio(); }