int WEqProcessor::SetParameters(int nPreAmpGain, int *pnBandGain, int nNumberOfBands) { ASSERT_W(c_eqParam); // check input parameters if(pnBandGain == 0) { strcpy(c_pchErrorMessageStr, "WEqProcessor::SetParameters->pnBandGain parameter can be 0."); return 0; } if(nNumberOfBands != c_nNumberOfBands) { sprintf(c_pchErrorMessageStr, "WEqProcessor::SetParameters->Number of bands must be %u.", c_nNumberOfBands); return 0; } c_nPreampGain = nPreAmpGain; int i; for(i = 0; i < nNumberOfBands; i++) c_eqParam[i].nGain = pnBandGain[i]; if(c_fEnable) _MakeEqTables(this); return 1; }
int WEqProcessor::GetBandGain(int nBandIndex) { ASSERT_W(c_eqParam); if(nBandIndex >= c_nNumberOfBands) return 0; return c_eqParam[nBandIndex].nGain; }
int WWaveIn::Seek(unsigned int nSamples) { ASSERT_W(c_fReady); err(DECODER_NO_ERROR); c_nCurrentPosition = 0; return 1; }
void WEqProcessor::_ClearBuffer(WEqProcessor *instance) { ASSERT_W(instance->outbuf); int i; instance->nbufsamples = 0; for(i = 0; i < TabSize * NCH; i++) instance->outbuf[i] = 0; }
int WEqProcessor::Enable(int fBroadcast, int fEnable) { ASSERT_W(c_eqParam); if(fEnable && c_fEnable) return 1; if(fEnable) { EnterCriticalSection(&c_CriticalSection); c_nLatencyInSamples = 0; // allocate internal memory if(_AllocateInternalMemory(this) == 0) { strcpy(c_pchErrorMessageStr, "WEqProcessor::Enable->Memory allocation error."); LeaveCriticalSection(&c_CriticalSection); return 0; } // create equ tables, need valid c_eqParam and c_nSampleRate _MakeEqTables(this); // set current latency, need this to fix equalizer latency c_nMaxLatencySamples = Latency; c_nCurrentEqLatency = Latency; c_fEnable = 1; LeaveCriticalSection(&c_CriticalSection); } else { c_fEnable = 0; Flush(0); } if(fBroadcast && c_next) { #ifdef AUDIO_PROCESSOR_RETURN_ERROR_STR if(c_pchReturnError == 0) c_next->c_pchReturnError = c_pchErrorMessageStr; else c_next->c_pchReturnError = c_pchReturnError; #endif return c_next->Enable(fBroadcast, fEnable); } return 1; }
int WEqProcessor::SetPreampGain(int nGain) { ASSERT_W(c_eqParam); c_nPreampGain = nGain; if(c_fEnable) _MakeEqTables(this); return 1; }
int WMp3Encoder::EncodeSamples(void *pSamples, unsigned int nNumberOfSamples) { ASSERT_W(c_nBitBerSample == 16); if(c_fReady == 0) { err(ENCODER_NOT_READY); return 0; } int nOutputBytes; short *samples = (short*) pSamples; unsigned int nHaveSamples = nNumberOfSamples; if(nNumberOfSamples == 0) { nOutputBytes = lame_encode_flush(gfp, c_pWorkingBuffer, c_nSamplesBufferSizeInBytes); if(nOutputBytes > 0) c_write_callback(c_pWorkingBuffer, nOutputBytes, c_user_data); // Chunk ID return 1; } while(nHaveSamples) { unsigned int nFill = c_NumberOfInputSamples; if(nFill > nHaveSamples) nFill = nHaveSamples; if ( 1 == lame_get_num_channels( gfp ) ) { nOutputBytes = lame_encode_buffer(gfp, samples, samples, nFill, c_pWorkingBuffer, 0); samples = &samples[nFill]; } else { nOutputBytes = lame_encode_buffer_interleaved(gfp, samples, nFill, c_pWorkingBuffer, 0); samples = &samples[nFill * 2]; } nHaveSamples -= nFill; if(nOutputBytes > 0) c_write_callback(c_pWorkingBuffer, nOutputBytes, c_user_data); // Chunk ID } return 1; }
size_t WOggDecoder::read_func(void *ptr, size_t size, size_t nmemb, void *datasource) { USER_OGG_STREAM *bit_stream = (USER_OGG_STREAM*) datasource; if(bit_stream->pos > bit_stream->end) return 0; // end of stream data unsigned int data_size = size * nmemb; unsigned int have = bit_stream->end - bit_stream->pos + 1; if(data_size > have) data_size = have; ASSERT_W(ptr); ASSERT_W(bit_stream->pos); memcpy(ptr, bit_stream->pos, data_size); unsigned int read_block_num = data_size / size; bit_stream->pos = bit_stream->pos + read_block_num * size; return read_block_num; }
int WEqProcessor::GetEqBands(int *pnFreqPoint, int nFreqPointNumber) { ASSERT_W(c_eqParam); if(pnFreqPoint == 0 || nFreqPointNumber == 0) return c_nNumberOfBands - 1; int i; int num = min(nFreqPointNumber, c_nNumberOfBands - 1); for(i = 0; i < num; i++) pnFreqPoint[i] = (int) c_eqParam[i].nFreqPoint; return num; }
int WEqProcessor::GetParameters(int *pnPreAmpGain, int *pnBandGain, int nNumberOfBands) { ASSERT_W(c_eqParam); if(pnPreAmpGain == 0 || pnBandGain == 0 || nNumberOfBands == 0) return c_nNumberOfBands; int i; int num = min(nNumberOfBands, c_nNumberOfBands); for(i = 0; i < num; i++) pnBandGain[i] = c_eqParam[i].nGain; *pnPreAmpGain = c_nPreampGain; return num; }
int WEqProcessor::SetBandGain(int nBandIndex, int nGain) { ASSERT_W(c_eqParam); if(nBandIndex >= c_nNumberOfBands) { strcpy(c_pchErrorMessageStr, "Invalid input parameter."); return 0; } c_eqParam[nBandIndex].nGain = nGain; if(c_fEnable) _MakeEqTables(this); return 1; }
int WInputProcessor::PushSamples(PROCESSOR_AUDIO_DATA *data) { // send data to next processor if(c_next) { #ifdef AUDIO_PROCESSOR_RETURN_ERROR_STR if(c_pchReturnError == 0) c_next->c_pchReturnError = c_pchErrorMessageStr; else c_next->c_pchReturnError = c_pchReturnError; #endif return c_next->PushSamples(data); } ASSERT_W(0); return 0; }
int WOggDecoder::Seek(unsigned int nSamples) { ASSERT_W(c_fReady); err(DECODER_NO_ERROR); c_nBufferSize = 0; if(c_fManagedStream) { err(DECODER_SEEK_NOT_SUPPORTED_MANAGED); return 0; } if(nSamples >= c_isInfo.nLength) { err(DECODER_SEEK_POSITION_OUT_OF_BOUNDS); return 0; } if(ov_seekable(&vf) == 0) { err(DECODER_UNKNOWN_ERROR); return 0; } if(ov_pcm_seek(&vf, nSamples) != 0) { err(DECODER_UNKNOWN_ERROR); return 0; } c_nCurrentPosition = nSamples; c_nReversePos = nSamples; return 1; }
int WOggDecoder::SetReverseMode(int fReverse) { ASSERT_W(c_fReady); err(DECODER_NO_ERROR); if(fReverse) { if(c_fManagedStream) { err(DECODER_REVERSE_NOT_SUPPORTED_MANAGED); return 0; } c_fReverse = 1; } else c_fReverse = 0; return 1; }
int WEqProcessor::GetPreampGain() { ASSERT_W(c_eqParam); return c_nPreampGain; }
INPUT_STREAM_INFO *WWaveIn::GetStreamInfo() { ASSERT_W(c_fReady); return &c_isInfo; }
int WOggDecoder::GetData(DECODER_DATA *pDecoderData) { ASSERT_W(c_fReady); ASSERT_W(pDecoderData); ASSERT_W(pDecoderData->pSamples); unsigned int nSamplesNeed = pDecoderData->nSamplesNum; // number of samples requested by user unsigned int nUserRequest = pDecoderData->nSamplesNum; unsigned int nSamplesHave = 0; unsigned int nBufferDone = 0; c_fEndOfStream = pDecoderData->fEndOfStream; int current_section = c_nLogicalBitstreamIndex; int ret; int *pchOutBuffer = (int*) pDecoderData->pSamples; // use int because here we are working always with 16 bit stereo samples // initialize this to 0 pDecoderData->nBufferDone = 0; pDecoderData->nBufferInQueue = 0; pDecoderData->nBytesInQueue = 0; pDecoderData->nSamplesNum = 0; pDecoderData->nStartPosition = 0; pDecoderData->nEndPosition = 0; c_nBufferDone = 0; while(nSamplesNeed) // try to get all data that user need { if(c_nBufferSize == 0) // we don't have any data in buffer, so get new data from decoder { unsigned int nBytesNeed = SIZE_OF_WORKING_BUFFER * c_nBlockAlign; // always use 16 bit stereo unsigned int nBytesHave = 0; if(c_fReverse) // seek back { if(c_nReversePos == 0) break; // move position back if(c_nReversePos >= SIZE_OF_WORKING_BUFFER) { c_nReversePos -= SIZE_OF_WORKING_BUFFER; } else { nSamplesNeed = c_nReversePos; c_nReversePos = 0; } if(ov_seekable(&vf) == 0) return DECODER_FATAL_ERROR; if(ov_pcm_seek(&vf, c_nReversePos) != 0) return DECODER_FATAL_ERROR; } // ===================================================================== // FILL WORKING BUFFER WITH DATA unsigned int nTryAgain = 0; char *buf = c_pBufferAlloc; while(nBytesNeed) { ret = ov_read(&vf, buf, nBytesNeed, 0,2,1, ¤t_section); nBufferDone += c_nBufferDone; switch(ret) { case OV_HOLE: // interruption in the data, try again { if(nTryAgain > 10) // prevent continuous loop { nBytesNeed = 0; } nTryAgain++; } break; case OV_EBADLINK: // invalid stream section was supplied to libvorbisfile, or the requested link is corrupt case 0: // end of file, stop loop nBytesNeed = 0; break; default: { // we have data from vorbis decoder nTryAgain = 0; if(c_nLogicalBitstreamIndex != current_section) continue; buf += ret; nBytesHave += ret; nBytesNeed -= ret; } break; } } if(nBytesHave == 0) break; c_nBufferSize = nBytesHave / c_nBlockAlign; c_pchBufferPos = (int*) c_pBufferAlloc; // ======================================================================= // CONVERT WORKING BUFFER INTO STEREO AND REVERSE IF NEEDED if(c_isInfo.nChannel == 1) PCM16MonoToPCM16Stereo((short*) c_pBufferAlloc, c_nBufferSize , (short*) c_pBufferAlloc); if(c_fReverse) PCM16StereoReverse((int*) c_pBufferAlloc, c_nBufferSize , (int*)c_pBufferAlloc); // loop again and use this data from working buffer } else { // we have some data in buffer, copy this data to user buffer if(c_nBufferSize >= nSamplesNeed) { // we have enough data in buffer, so we have all data that user needs unsigned int i; for(i = 0; i < nSamplesNeed; i++) pchOutBuffer[i] = c_pchBufferPos[i]; nSamplesHave += nSamplesNeed; // move pointer to next sample in buffer, need this for next call to GetData c_pchBufferPos = &c_pchBufferPos[nSamplesNeed]; // calculate number of remaining samples in buffer c_nBufferSize -= nSamplesNeed; // we have all samples we need, don't loop anymore nSamplesNeed = 0; } else { // we don't have enough data in buffer, use what we have unsigned int i; for(i = 0; i < c_nBufferSize; i++) pchOutBuffer[i] = c_pchBufferPos[i]; nSamplesHave += c_nBufferSize; // calculate number of samples we need nSamplesNeed -= c_nBufferSize; // move pointer of user buffer pchOutBuffer = &pchOutBuffer[c_nBufferSize]; // buffer is now empty c_nBufferSize = 0; } } } if(nBufferDone) { pDecoderData->nBufferDone = nBufferDone; pDecoderData->nBufferInQueue = c_Queue->GetCount(); pDecoderData->nBytesInQueue = c_Queue->GetSizeSum(); } if(c_fManagedStream) { // we will not return partial data, unless user specified end of stream if(nSamplesHave < nUserRequest && c_fEndOfStream == 0) { // we need to save data from user buffer into internal buffer // check if we need to reallocate internal buffer if(c_nBufferAllocSize < nSamplesHave) { char *tmp = (char*) malloc(nSamplesHave * 4); // always use 16 bit stereo if(tmp == 0) return DECODER_FATAL_ERROR; free(c_pBufferAlloc); c_pBufferAlloc = tmp; c_nBufferAllocSize = nSamplesHave; } c_pchBufferPos = (int*) c_pBufferAlloc; pchOutBuffer = (int*) pDecoderData->pSamples; // move data from user buffer into internal buffer unsigned int i; for(i = 0; i < nSamplesHave; i++) c_pchBufferPos[i] = pchOutBuffer[i]; c_nBufferSize = nSamplesHave; return DECODER_MANAGED_NEED_MORE_DATA; } } if(nSamplesHave == 0) { if(c_fManagedStream) { if(c_fEndOfStream) return DECODER_END_OF_DATA; return DECODER_MANAGED_NEED_MORE_DATA; } return DECODER_END_OF_DATA; } pDecoderData->nSamplesNum = nSamplesHave; pDecoderData->nStartPosition = c_nCurrentPosition; if(c_fReverse) c_nCurrentPosition -= nSamplesHave; else c_nCurrentPosition += nSamplesHave; pDecoderData->nEndPosition = c_nCurrentPosition; return DECODER_OK; }
int WWaveIn::GetData(DECODER_DATA *pDecoderData) { ASSERT_W(c_fReady); ASSERT_W(pDecoderData); ASSERT_W(pDecoderData->pSamples); pDecoderData->nBufferDone = 0; pDecoderData->nBufferInQueue = 0; pDecoderData->nBytesInQueue = 0; unsigned int nSamplesNeed = pDecoderData->nSamplesNum; unsigned int nBytesNeed = pDecoderData->nSamplesNum * 4; unsigned int nBytesHave = 0; unsigned int nSamplesHave = nBytesHave / 4; unsigned int nWait = 0; while(nWait < 8) { EnterCriticalSection(&cs); nBytesHave = c_Queue.GetSizeSum(); LeaveCriticalSection(&cs); nWait++; if(nBytesHave < nBytesNeed) { Sleep(AUDIO_BUFFER_SIZE / 4); continue; } break; } EnterCriticalSection(&cs); nBytesHave = c_Queue.GetSizeSum(); LeaveCriticalSection(&cs); if(nBytesHave < nBytesNeed) { // return blank samples memset(pDecoderData->pSamples, 0, nBytesNeed); pDecoderData->nSamplesNum = nSamplesNeed; } else { // get samples from queue int out; EnterCriticalSection(&cs); unsigned int ret = c_Queue.PullDataFifo(pDecoderData->pSamples, nBytesNeed, &out); LeaveCriticalSection(&cs); if(ret == 0) { // return blank samples memset(pDecoderData->pSamples, 0, nBytesNeed); pDecoderData->nSamplesNum = nSamplesNeed; } else pDecoderData->nSamplesNum = ret / 4; } pDecoderData->nStartPosition = c_nCurrentPosition; c_nCurrentPosition += pDecoderData->nSamplesNum; pDecoderData->nEndPosition = c_nCurrentPosition; return DECODER_OK; }
int WWaveIn::SetReverseMode(int fReverse) { ASSERT_W(c_fReady); err(DECODER_REVERSE_NOT_SUPPORTED_MANAGED); return 0; }
INPUT_STREAM_INFO *WOggDecoder::GetStreamInfo() { ASSERT_W(c_fReady); return &c_isInfo; }