/* queues audio frames in an IOQueue, allows streaming from frames Copyright (C) 2001 Martin Vogt This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation. For more information look at the file COPYRIGHT in this package */ #include "audioFrameQueue.h" #define _FLOAT_2_TRANSFER 1 #define _FLOAT_1_TRANSFER 2 #define _INT_2_TRANSFER 3 #define _INT_1_TRANSFER 4 #define _FORWARD_TRANSFER 5 #include using namespace std; AudioFrameQueue::AudioFrameQueue(int queueSize, int frameSize, int frameType):IOFrameQueue(queueSize) { switch(frameType) { case _FRAME_AUDIO_PCM: { // fill queue with elements while(emptyQueueCanWrite()) { PCMFrame* pcmFrame=new PCMFrame(frameSize); emptyQueueEnqueue(pcmFrame); } break; } case _FRAME_AUDIO_FLOAT: { // fill queue with elements while(emptyQueueCanWrite()) { FloatFrame* floatFrame=new FloatFrame(frameSize); emptyQueueEnqueue(floatFrame); } break; } default: cout << "unknown frameType:"<frameType=frameType; } AudioFrameQueue::~AudioFrameQueue() { delete currentAudioFrame; } void AudioFrameQueue::emptyQueueEnqueue(AudioFrame* frame) { empty->enqueue(frame); } AudioFrame* AudioFrameQueue::emptyQueueDequeue() { return (AudioFrame*)empty->dequeue(); } void AudioFrameQueue::dataQueueEnqueue(AudioFrame* frame) { if (data->getFillgrade() == 0) { frame->copyFormat(currentAudioFrame); } len+=frame->getLen(); data->enqueue(frame); } AudioFrame* AudioFrameQueue::dataQueueDequeue() { AudioFrame* back=(AudioFrame*)data->dequeue(); currentRead=0; len-=back->getLen(); back->copyFormat(currentAudioFrame); return back; } AudioFrame* AudioFrameQueue::getCurrent() { return currentAudioFrame; } int AudioFrameQueue::getLen() { return len-currentRead; } int AudioFrameQueue::copy(float* left,float* right,int wantLen) { if (frameType != _FRAME_AUDIO_FLOAT) { cout << "AudioFrameQueue::copy class is frameType short int"<getStereo()) { wantLen*=2; mux=2; } int back=copygeneric((char*)left,(char*)right, wantLen,_FLOAT_2_TRANSFER,mux); if (currentAudioFrame->getStereo()) back/=2; return back; } int AudioFrameQueue::copy(short int* left,short int* right,int wantLen) { if (frameType != _FRAME_AUDIO_PCM) { cout << "AudioFrameQueue::copy class is frameType float"<getStereo()) { wantLen*=2; mux=2; } int back=copygeneric((char*)left,(char*)right, wantLen,_INT_2_TRANSFER,mux); if (currentAudioFrame->getStereo()) back/=2; return back; } int AudioFrameQueue::copy(short int* dest,int wantLen) { if (frameType != _FRAME_AUDIO_PCM) { cout << "AudioFrameQueue::copy class is frameType int single"<getStereo()) { forwardLen*=2; } int back=copygeneric((char*)NULL,(char*)NULL, forwardLen,_FORWARD_TRANSFER,mux); if (back != forwardLen) { cout << "error while forwarding stream"< (len-processed)) { wantLen=len-processed; } int pos=0; int doLen=wantLen; while(doLen > 0) { AudioFrame* current=(AudioFrame*)data->peekqueue(pos); int totallen=current->getLen(); int restlen=totallen-processed; int copylen=doLen; if (doLen > restlen) { copylen=restlen; } doLen-=copylen; switch(version) { case _FLOAT_2_TRANSFER: transferFrame((float*)left, (float*)right, (FloatFrame*) current,processed,copylen); left+=copylen/mux*(sizeof(float)); right+=copylen/mux*(sizeof(float)); break; case _FLOAT_1_TRANSFER: transferFrame((float*)left, (FloatFrame*) current,processed,copylen); left+=copylen*sizeof(short int); break; case _INT_2_TRANSFER: transferFrame((short int*)left, (short int*)right, (PCMFrame*) current,processed,copylen); left+=copylen/mux*(sizeof(short int)); right+=copylen/mux*(sizeof(short int)); break; case _INT_1_TRANSFER: transferFrame((short int*)left, (PCMFrame*) current,processed,copylen); left+=copylen*sizeof(short int); break; case _FORWARD_TRANSFER: break; default: cout << "unknown transfer method AudioFrameQueue::copygeneric"<getData()+start; switch(currentAudioFrame->getStereo()) { case true: len=len/2; while(len) { *left++=*ptr++; *right++=*ptr++; len--; } break; case false: while(len) { *left++=*ptr; *right++=*ptr++; len--; } break; default: cout << "bad stereo value AudioFrameQueue::transferFrame (float)"<getData()+start; switch(currentAudioFrame->getStereo()) { case true: len=len/2; while(len) { *left++=*ptr++; *right++=*ptr++; len--; } break; case false: while(len) { *left++=*ptr; *right++=*ptr++; len--; } break; default: cout << "bad stereo value AudioFrameQueue::transferFrame (int)"<getData()+start; memcpy(dest,ptr,len*sizeof(short int)); } void AudioFrameQueue::transferFrame(float* dest, FloatFrame* current,int start,int len) { float* ptr=current->getData()+start; memcpy(dest,ptr,len*sizeof(float)); } void AudioFrameQueue::clear() { while(dataQueueCanRead()) { AudioFrame* current=dataQueueDequeue(); emptyQueueEnqueue(current); } }