Beispiel #1
0
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;
}
Beispiel #5
0
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;
}
Beispiel #7
0
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;
}
Beispiel #9
0
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__);
}
Beispiel #10
0
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__);
}
Beispiel #11
0
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__);
}
Beispiel #12
0
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__);
}
Beispiel #14
0
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;
}