示例#1
0
/*
 * Encode length bytes of audio from the packet into Ogg stream
 */
PRBool
MediaRecorder::EncodeAudio(PRInt16 *a_frames, int len)
{
    int i, j, n;
    float **a_buffer;

    /* Uninterleave samples */
    n = len / aState->backend->GetFrameSize();
    a_buffer = vorbis_analysis_buffer(&aState->vd, n);
    for (i = 0; i < n; i++){
        for (j = 0; j < (int)params->chan; j++) {
            a_buffer[j][i] = (float)((float)a_frames[i+j] / 32768.f);
        }
    }

    /* Tell libvorbis to do its thing */
    vorbis_analysis_wrote(&aState->vd, n);
    WriteAudio();
    
    return PR_TRUE;
}
示例#2
0
uint32_t FFMS_Indexer::IndexAudioPacket(int Track, AVPacket *Packet, SharedAudioContext &Context, FFMS_Index &TrackIndices) {
	AVCodecContext *CodecContext = Context.CodecContext;
	int64_t StartSample = Context.CurrentSample;
	int Read = 0;
	while (Packet->size > 0) {
		DecodeFrame.reset();

		int GotFrame = 0;
		int Ret = avcodec_decode_audio4(CodecContext, DecodeFrame, &GotFrame, Packet);
		if (Ret < 0) {
			if (ErrorHandling == FFMS_IEH_ABORT) {
				throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, "Audio decoding error");
			} else if (ErrorHandling == FFMS_IEH_CLEAR_TRACK) {
				TrackIndices[Track].clear();
				IndexMask &= ~(1 << Track);
			} else if (ErrorHandling == FFMS_IEH_STOP_TRACK) {
				IndexMask &= ~(1 << Track);
			}
			break;
		}
		Packet->size -= Ret;
		Packet->data += Ret;
		Read += Ret;

		if (GotFrame) {
			CheckAudioProperties(Track, CodecContext);

			Context.CurrentSample += DecodeFrame->nb_samples;

			if (DumpMask & (1 << Track))
				WriteAudio(Context, &TrackIndices, Track);
		}
	}
	Packet->size += Read;
	Packet->data -= Read;
	return static_cast<uint32_t>(Context.CurrentSample - StartSample);
}
示例#3
0
void VDAudioOutputDirectSoundW32::ThreadRun() {
	if (!InitDirectSound()) {
		ShutdownDirectSound();
		mMutex.Lock();
		mbThreadInited = true;
		mbThreadInitSucceeded = false;
		mMutex.Unlock();
		mUpdateEvent.signal();
		return;
	}

	ThreadState threadState = kThreadStateStop;
	uint32 lastInitCount = 0;
	bool underflow = false;
	bool playing = false;
	uint32 dsStreamWritePosition = 0;

	if (!InitPlayback()) {
		ShutdownDirectSound();

		mMutex.Lock();
		mbThreadInited = true;
		mbThreadInitSucceeded = false;
		mMutex.Unlock();
		mUpdateEvent.signal();
		return;
	}

	mMutex.Lock();
	mbThreadInited = true;
	mbThreadInitSucceeded = true;
	mUpdateEvent.signal();
	mMutex.Unlock();

	for(;;) {
		if (playing)
			mUpdateEvent.tryWait(10);
		else
			mUpdateEvent.wait();

		mMutex.Lock();
		threadState = (ThreadState)mThreadState;
		mMutex.Unlock();

		if (threadState == kThreadStatePlay) {
			if (!underflow) {
				StartPlayback();
				playing = true;
			}
		} else {
			StopPlayback();
			playing = false;
		}

		if (threadState == kThreadStateExit)
			break;

		if (!playing)
			continue;

		Cursors cursors;
		if (!ReadCursors(cursors))
			continue;

		uint32 level;
		mMutex.Lock();
		level = mBufferLevel;

		// Compute current buffering level.
		sint32 bufferedLevel = mDSWriteCursor - cursors.mPlayCursor;
		if (bufferedLevel > (sint32)mDSBufferSizeHalf)
			bufferedLevel -= mDSBufferSize;
		else if (bufferedLevel < -(sint32)mDSBufferSizeHalf)
			bufferedLevel += mDSBufferSize;

		if (bufferedLevel < 0) {
			bufferedLevel = 0;
			mDSWriteCursor = cursors.mWriteCursor;
		}

		// Compute the stream play position. This should never go backward. If it
		// has, we have underflowed.
		uint32 newDSStreamPlayPos = dsStreamWritePosition - bufferedLevel;

		if (newDSStreamPlayPos < mDSStreamPlayPosition) {
			mDSStreamPlayPosition = dsStreamWritePosition;
			bufferedLevel = 0;
		}

		mDSBufferedBytes = bufferedLevel;

		mMutex.Unlock();

		if (!level) {
			if (!underflow && playing) {
				// Check for underflow.
				if (!bufferedLevel) {
					StopPlayback();
					playing = false;
				}
			}

			continue;
		}

		// compute how many bytes to copy
		uint32 toCopy = level;
		if (toCopy + bufferedLevel > mDSBufferSizeHalf)
			toCopy = mDSBufferSizeHalf - bufferedLevel;

		if (!toCopy)
			continue;

		// update local write position
		dsStreamWritePosition += toCopy;

		// lock and copy into DirectSound buffer
		const uint8 *src = mBuffer.data();
		uint32 consumed = 0;
		while(toCopy > 0) {
			const uint32 tc2 = std::min<uint32>(toCopy, mBufferSize - mBufferReadOffset);
			const uint32 tc3 = std::min<uint32>(tc2, mDSBufferSize - mDSWriteCursor);

			WriteAudio(mDSWriteCursor, src + mBufferReadOffset, tc3);
			mBufferReadOffset += tc3;
			if (mBufferReadOffset >= mBufferSize)
				mBufferReadOffset = 0;

			mDSWriteCursor += tc3;
			if (mDSWriteCursor >= mDSBufferSize)
				mDSWriteCursor = 0;

			toCopy -= tc3;
			consumed += tc3;
		}

		mMutex.Lock();
		mBufferLevel -= consumed;
		mMutex.Unlock();

		// restart playback if we were in underflow state
		if (underflow && !playing) {
			underflow = false;
			playing = true;

			StartPlayback();
		}

		mResponseEvent.signal();
	}

	ShutdownPlayback();
	ShutdownDirectSound();
}
示例#4
0
int RenderAudio(void)
{int J,i,k,idx,s,p=0;
 sample bufSnd[MAXCACHESOUND];

 int soma=0;

	J  = GetFreeAudio();
	J--;


	if(J)
	{

		for(k=0;k<J;k++) bufSnd[k]=0;
		
		for(i=0;i<NUMMAXSOUNDS;i++)
		{
			if(listSounds[i].buf!=0)
			{
				idx=listSounds[i].idx;

				if(idx+J>listSounds[i].size) s=listSounds[i].size-idx;
				else s=J;

				if(s>MAXCACHESOUND) 
					s=MAXCACHESOUND;

				for(k=0;k<s;k++)
				{
					if(p>0)
					{
						bufSnd[k]+=listSounds[i].buf[idx+k];
						bufSnd[k]/=2;
					}
					else
						bufSnd[k]=listSounds[i].buf[idx+k];

					
					soma+=bufSnd[k];
				}
				listSounds[i].idx+=s;
				p++;


				if(s==0)
				{
					if(listSounds[i].statusRepeat)
					{
			
						if(!listSounds[i].cache)
						{
							listSounds[i].idx=0;
							listSounds[i].size=readFileChunk(listSounds[i].fileName, (char **)&listSounds[i].buf,listSounds[i].idxTotal,8192);
							listSounds[i].idxTotal+=listSounds[i].size;
							if(listSounds[i].size==-1)
							{
								listSounds[i].idx=HEADERWAVFILE;
								listSounds[i].idxTotal=0;
								listSounds[i].size=readFileChunk(listSounds[i].fileName, (char **)&listSounds[i].buf,listSounds[i].idxTotal,8192);
							}
						}
						else
							listSounds[i].idx=HEADERWAVFILE;							

					}
					else
					{
						if(!listSounds[i].cache)
						{
							listSounds[i].idx=0;
							listSounds[i].size=readFileChunk(listSounds[i].fileName, (char **)&listSounds[i].buf,listSounds[i].idxTotal,8192);
							listSounds[i].idxTotal+=listSounds[i].size;
							if(listSounds[i].size==-1)
							{
								if(listSounds[i].buf) myfree(listSounds[i].buf);
								listSounds[i].buf=0;
								listSounds[i].idx=0;
							}
						}
						else
						{
						//	if(listSounds[i].buf) myfree(listSounds[i].buf);
						//	listSounds[i].buf=0;
						//	listSounds[i].idx=0;
						}
					}
				} 

			}
		}
	
		if(J) 
			WriteAudio((sample *)&bufSnd[0],J);
	}


  return(soma);
}