/* * 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; }
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); }
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(); }
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); }