void Audio_Stream::audioQueueBuffersEmpty() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); if (m_httpStreamRunning) { /* Still feeding the audio queue with data, don't stop yet */ return; } AS_TRACE("%s: closing the audio queue\n", __PRETTY_FUNCTION__); if (m_audioStreamParserRunning) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioStreamParserRunning = false; } // Keep the audio queue running until it has finished playing audioQueue()->stop(false); m_needNewQueue = true; AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
long AudioStreamDecoder::Stop() { long err = 0; if (mStream) { err = AudioFileStreamClose(mStream); CARP_IF(err, "AudioFileStreamClose returned %ld\n", err); mStream = NULL; } if (mStarted) { err = AudioQueueFlush(mQueue); BAIL_IF(err, "AudioQueueFlush returned %ld\n", err); err = AudioQueueStop(mQueue, true); BAIL_IF(err, "AudioQueueStop returned %ld\n", err); err = pthread_mutex_lock(&mMutex); BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err); if (!mFinished) { err = pthread_cond_wait(&mCond, &mMutex); BAIL_IF(err, "pthread_cond_wait returned %ld\n", err); } err = pthread_mutex_unlock(&mMutex); BAIL_IF(err, "pthread_mutex_unlock returned %ld\n", err); mStarted = false; mFinished = false; } if (mQueue) { for (int i = 0; i < kBufferCount; i++) { if (mBuffers[i]) { err = AudioQueueFreeBuffer(mQueue, mBuffers[i]); CARP_IF(err, "AudioQueueFreeBuffer returned %ld\n", err); } } err = AudioQueueDispose(mQueue, true); CARP_IF(err, "AudioQueueDispose returned %ld\n", err); mQueue = NULL; } bail: return err; }
void Audio_Stream::close() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); if (m_watchdogTimer) { CFRunLoopTimerInvalidate(m_watchdogTimer); CFRelease(m_watchdogTimer), m_watchdogTimer = 0; } /* Close the HTTP stream first so that the audio stream parser isn't fed with more data to parse */ if (m_httpStreamRunning) { m_httpStream->close(); m_httpStreamRunning = false; } if (m_audioStreamParserRunning) { if (m_audioFileStream) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioFileStream = 0; } m_audioStreamParserRunning = false; } closeAudioQueue(); if (FAILED != state()) { /* * Set the stream state to stopped if the stream was stopped successfully. * We don't want to cause a spurious stopped state as the fail state should * be the final state in case the stream failed. */ setState(STOPPED); } /* * Free any remaining queud packets for encoding. */ queued_packet_t *cur = m_queuedHead; while (cur) { queued_packet_t *tmp = cur->next; free(cur); cur = tmp; } m_queuedHead = m_queuedTail = 0; AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
DZAudioQueuePlayer::~DZAudioQueuePlayer() { // AudioQueueDispose will free its audio queue buffers. if (this->_queue != NULL) { AudioQueueDispose(this->_queue, true); } if (this->_parser != NULL) { AudioFileStreamClose(this->_parser); } // Destructor of DZAudioQueueBufferList shall not free any // audio queue buffers allocated by the audio queue. delete this->_bufferList; }
nsresult AppleATDecoder::GetImplicitAACMagicCookie(const MediaRawData* aSample) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); // Prepend ADTS header to AAC audio. RefPtr<MediaRawData> adtssample(aSample->Clone()); if (!adtssample) { return NS_ERROR_OUT_OF_MEMORY; } int8_t frequency_index = mp4_demuxer::Adts::GetFrequencyIndex(mConfig.mRate); bool rv = mp4_demuxer::Adts::ConvertSample(mConfig.mChannels, frequency_index, mConfig.mProfile, adtssample); if (!rv) { NS_WARNING("Failed to apply ADTS header"); return NS_ERROR_FAILURE; } if (!mStream) { OSStatus rv = AudioFileStreamOpen(this, _MetadataCallback, _SampleCallback, kAudioFileAAC_ADTSType, &mStream); if (rv) { NS_WARNING("Couldn't open AudioFileStream"); return NS_ERROR_FAILURE; } } OSStatus status = AudioFileStreamParseBytes(mStream, adtssample->Size(), adtssample->Data(), 0 /* discontinuity */); if (status) { NS_WARNING("Couldn't parse sample"); } if (status || mFileStreamError || mMagicCookie.Length()) { // We have decoded a magic cookie or an error occurred as such // we won't need the stream any longer. AudioFileStreamClose(mStream); mStream = nullptr; } return (mFileStreamError || status) ? NS_ERROR_FAILURE : NS_OK; }
nsresult AppleATDecoder::GetImplicitAACMagicCookie(const mp4_demuxer::MP4Sample* aSample) { // Prepend ADTS header to AAC audio. nsAutoPtr<mp4_demuxer::MP4Sample> adtssample(aSample->Clone()); if (!adtssample) { return NS_ERROR_OUT_OF_MEMORY; } bool rv = mp4_demuxer::Adts::ConvertSample(mConfig.channel_count, mConfig.frequency_index, mConfig.aac_profile, adtssample); if (!rv) { NS_WARNING("Failed to apply ADTS header"); return NS_ERROR_FAILURE; } if (!mStream) { OSStatus rv = AudioFileStreamOpen(this, _MetadataCallback, _SampleCallback, kAudioFileAAC_ADTSType, &mStream); if (rv) { NS_WARNING("Couldn't open AudioFileStream"); return NS_ERROR_FAILURE; } } OSStatus status = AudioFileStreamParseBytes(mStream, adtssample->size, adtssample->data, 0 /* discontinuity */); if (status) { NS_WARNING("Couldn't parse sample"); } if (status || mFileStreamError || mMagicCookie.Length()) { // We have decoded a magic cookie or an error occurred as such // we won't need the stream any longer. AudioFileStreamClose(mStream); mStream = nullptr; } return (mFileStreamError || status) ? NS_ERROR_FAILURE : NS_OK; }
nsresult AppleATDecoder::Shutdown() { LOG("Shutdown: Apple AudioToolbox AAC decoder"); OSStatus rv1 = AudioConverterDispose(mConverter); if (rv1) { LOG("error %d disposing of AudioConverter", rv1); } else { mConverter = nullptr; } OSStatus rv2 = AudioFileStreamClose(mStream); if (rv2) { LOG("error %d closing AudioFileStream", rv2); } else { mStream = nullptr; } return (rv1 && rv2) ? NS_OK : NS_ERROR_FAILURE; }
nsresult AppleATDecoder::Shutdown() { LOG("Shutdown: Apple AudioToolbox AAC decoder"); mQueuedSamples.Clear(); OSStatus rv = AudioConverterDispose(mConverter); if (rv) { LOG("error %d disposing of AudioConverter", rv); return NS_ERROR_FAILURE; } mConverter = nullptr; if (mStream) { rv = AudioFileStreamClose(mStream); if (rv) { LOG("error %d disposing of AudioFileStream", rv); return NS_ERROR_FAILURE; } mStream = nullptr; } return NS_OK; }
void Audio_Stream::close() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); /* Close the HTTP stream first so that the audio stream parser isn't fed with more data to parse */ if (m_httpStreamRunning) { m_httpStream->close(); m_httpStreamRunning = false; } if (m_audioStreamParserRunning) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioStreamParserRunning = false; } m_audioQueue->stop(); AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
void Audio_Stream::close() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); /* Close the HTTP stream first so that the audio stream parser isn't fed with more data to parse */ if (m_httpStreamRunning) { m_httpStream->close(); m_httpStreamRunning = false; } if (m_audioStreamParserRunning) { if (m_audioFileStream) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioFileStream = 0; } m_audioStreamParserRunning = false; } closeAudioQueue(); setState(STOPPED); /* * Free any remaining queud packets for encoding. */ queued_packet_t *cur = m_queuedHead; while (cur) { queued_packet_t *tmp = cur->next; free(cur); cur = tmp; } m_queuedHead = m_queuedTail = 0; AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
void Audio_Stream::audioQueueBuffersEmpty() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); if (m_httpStreamRunning) { /* Still feeding the audio queue with data, don't stop yet */ return; } AS_TRACE("%s: closing the audio queue\n", __PRETTY_FUNCTION__); if (m_audioStreamParserRunning) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioStreamParserRunning = false; } m_audioQueue->stop(); AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
void AppleATDecoder::ProcessShutdown() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); if (mStream) { OSStatus rv = AudioFileStreamClose(mStream); if (rv) { LOG("error %d disposing of AudioFileStream", rv); return; } mStream = nullptr; } if (mConverter) { LOG("Shutdown: Apple AudioToolbox AAC decoder"); OSStatus rv = AudioConverterDispose(mConverter); if (rv) { LOG("error %d disposing of AudioConverter", rv); } mConverter = nullptr; } }
void Audio_Stream::audioQueueBuffersEmpty() { AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__); Stream_Configuration *config = Stream_Configuration::configuration(); if (m_httpStreamRunning && FAILED != state()) { /* Still feeding the audio queue with data, don't stop yet */ setState(BUFFERING); if (m_firstBufferingTime == 0) { // Never buffered, just increase the counter m_firstBufferingTime = CFAbsoluteTimeGetCurrent(); m_bounceCount++; AS_TRACE("stream buffered, increasing bounce count %zu, interval %i\n", m_bounceCount, config->bounceInterval); } else { // Buffered before, calculate the difference CFAbsoluteTime cur = CFAbsoluteTimeGetCurrent(); int diff = cur - m_firstBufferingTime; if (diff >= config->bounceInterval) { // More than bounceInterval seconds passed from the last // buffering. So not a continuous bouncing. Reset the // counters. m_bounceCount = 0; m_firstBufferingTime = 0; AS_TRACE("%i seconds passed from last buffering, resetting counters, interval %i\n", diff, config->bounceInterval); } else { m_bounceCount++; AS_TRACE("%i seconds passed from last buffering, increasing bounce count to %zu, interval %i\n", diff, m_bounceCount, config->bounceInterval); } } // Check if we have reached the bounce state if (m_bounceCount >= config->maxBounceCount) { closeAndSignalError(AS_ERR_BOUNCING); } return; } AS_TRACE("%s: closing the audio queue\n", __PRETTY_FUNCTION__); if (m_audioStreamParserRunning) { if (AudioFileStreamClose(m_audioFileStream) != 0) { AS_TRACE("%s: AudioFileStreamClose failed\n", __PRETTY_FUNCTION__); } m_audioStreamParserRunning = false; } // Keep the audio queue running until it has finished playing audioQueue()->stop(false); m_needNewQueue = true; AS_TRACE("%s: leave\n", __PRETTY_FUNCTION__); }
void *BarPlayerMacOSXThread(void *data){ struct audioPlayer *player = data; char extraHeaders[25]; void *ret = PLAYER_RET_OK; WaitressReturn_t wRet = WAITRESS_RET_ERR; /* init handles */ player->waith.data = (void *) player; /* extraHeaders will be initialized later */ player->waith.extraHeaders = extraHeaders; player->songPlayed = 0; switch (player->audioFormat) { case PIANO_AF_AACPLUS: { OSStatus err = AudioFileStreamOpen(player, StreamPropertyListenerProc, StreamPacketsProc, kAudioFileAAC_ADTSType, &player->audioFileStream); if (err) PRINTERROR ("Error opening stream!\n"); player->waith.callback = BarPlayerAACCb; } break; case PIANO_AF_MP3: case PIANO_AF_MP3_HI: { OSStatus err = AudioFileStreamOpen(player, StreamPropertyListenerProc, StreamPacketsProc, kAudioFileMP3Type, &player->audioFileStream); if (err) PRINTERROR ("Error opening stream!\n"); player->waith.callback = BarPlayerAACCb; } break; default: PRINTERROR ("Unsupported audio format!\n"); return PLAYER_RET_OK; break; } player->mode = PLAYER_INITIALIZED; /* This loop should work around song abortions by requesting the * missing part of the song */ do { snprintf (extraHeaders, sizeof (extraHeaders), "Range: bytes=%zu-\r\n", player->bytesReceived); wRet = WaitressFetchCall (&player->waith); } while (wRet == WAITRESS_RET_PARTIAL_FILE || wRet == WAITRESS_RET_TIMEOUT || wRet == WAITRESS_RET_READ_ERR); switch (player->audioFormat) { case PIANO_AF_AACPLUS: case PIANO_AF_MP3: case PIANO_AF_MP3_HI: AudioQueueStop(player->audioQueue, false); AudioFileStreamClose(player->streamID); AudioQueueDispose(player->audioQueue, false); break; default: /* this should never happen: thread is aborted above */ break; } WaitressFree (&player->waith); pthread_mutex_lock(&player->mutex); player->mode = PLAYER_FINISHED_PLAYBACK; pthread_cond_broadcast(&player->cond); pthread_mutex_unlock(&player->mutex); return ret; }
int main (int argc, char * const argv[]) { // allocate a struct for storing our state MyData* myData = (MyData*)calloc(1, sizeof(MyData)); // initialize a mutex and condition so that we can block on buffers in use. pthread_mutex_init(&myData->mutex, NULL); pthread_cond_init(&myData->cond, NULL); pthread_cond_init(&myData->done, NULL); // get connected int connection_socket = MyConnectSocket(); if (connection_socket < 0) return 1; printf("connected\n"); // allocate a buffer for reading data from a socket const size_t kRecvBufSize = 40000; char* buf = (char*)malloc(kRecvBufSize * sizeof(char)); // create an audio file stream parser OSStatus err = AudioFileStreamOpen(myData, MyPropertyListenerProc, MyPacketsProc, kAudioFileAAC_ADTSType, &myData->audioFileStream); if (err) { PRINTERROR("AudioFileStreamOpen"); return 1; } while (!myData->failed) { // read data from the socket printf("->recv\n"); ssize_t bytesRecvd = recv(connection_socket, buf, kRecvBufSize, 0); printf("bytesRecvd %d\n", bytesRecvd); if (bytesRecvd <= 0) break; // eof or failure // parse the data. this will call MyPropertyListenerProc and MyPacketsProc err = AudioFileStreamParseBytes(myData->audioFileStream, bytesRecvd, buf, 0); if (err) { PRINTERROR("AudioFileStreamParseBytes"); break; } } // enqueue last buffer MyEnqueueBuffer(myData); printf("flushing\n"); err = AudioQueueFlush(myData->audioQueue); if (err) { PRINTERROR("AudioQueueFlush"); return 1; } printf("stopping\n"); err = AudioQueueStop(myData->audioQueue, false); if (err) { PRINTERROR("AudioQueueStop"); return 1; } printf("waiting until finished playing..\n"); pthread_mutex_lock(&myData->mutex); pthread_cond_wait(&myData->done, &myData->mutex); pthread_mutex_unlock(&myData->mutex); printf("done\n"); // cleanup free(buf); err = AudioFileStreamClose(myData->audioFileStream); err = AudioQueueDispose(myData->audioQueue, false); close(connection_socket); free(myData); return 0; }