Beispiel #1
0
    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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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
}
Beispiel #6
0
/**
 * 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();
}