summaryrefslogtreecommitdiffstats
path: root/mpeglib/example/splay/mp3framing.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /mpeglib/example/splay/mp3framing.cpp
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpeglib/example/splay/mp3framing.cpp')
-rw-r--r--mpeglib/example/splay/mp3framing.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/mpeglib/example/splay/mp3framing.cpp b/mpeglib/example/splay/mp3framing.cpp
new file mode 100644
index 00000000..586899a3
--- /dev/null
+++ b/mpeglib/example/splay/mp3framing.cpp
@@ -0,0 +1,274 @@
+/*
+
+ Example how frame creation works.
+
+ For the input we have std. file input.
+ We convert it to mpeg I encoded frames (mpegAudioFrame's job)
+
+ The decoded pcmFrames are stores in a queue.
+
+ If the queue if full, we "stream" the packets to /dev/dsp.
+ (The difference between directly playing the packets and "streaming"
+ is, that while streaming you can say: I want x bytes I don't care
+ about frame boundaries)
+ This is audioFrameQueue's job.
+
+
+ */
+
+
+#include "../../lib/splay/mpegAudioFrame.h"
+#include "../../lib/splay/splayDecoder.h"
+#include "../../lib/util/audio/dspWrapper.h"
+#include "../../lib/frame/audioFrameQueue.h"
+
+#include <iostream>
+
+using namespace std;
+
+// used for getopt
+#include <unistd.h>
+
+#define INPUT_SIZE 8192
+#define _QUEUE_FLOAT 1
+#define _QUEUE_INT 2
+
+
+void usage() {
+ printf("Usage:\n\n");
+ printf("mp3framing [hf] filename\n\n");
+ printf(" -f use float queue\n");
+ printf(" -c [samples] checkout samples\n");
+}
+
+
+void initDSP(DSPWrapper* dsp) {
+ if (dsp->openDevice()==false) {
+ cout << "cannot open /dev/dsp"<<endl;
+ exit(-1);
+ }
+}
+
+
+
+int main(int argc, char** argv) {
+ int queueType=_QUEUE_INT;
+ int samples=8192;
+
+ PCMFrame* outFrame;
+
+ while(1) {
+ int c = getopt (argc, argv, "hfc:");
+ if (c == -1) break;
+ switch(c) {
+ case 'h': {
+ usage();
+ exit(-1);
+ break;
+ }
+ case 'f': {
+ queueType=_QUEUE_FLOAT;
+ break;
+ }
+ case 'c': {
+ samples=atoi(optarg);
+ cout << "checking out samples:samples"<<endl;
+ break;
+ }
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ exit(-1);
+ }
+ }
+ // if we have nothing left, there is no filename
+ if (optind >= argc ) {
+ usage();
+ exit(-1);
+ }
+ FILE* file=fopen(argv[optind],"r");
+ if (file == NULL) {
+ cout << "cannot open:"<<argv[1]<<endl;
+ exit(-1);
+ }
+ DSPWrapper* dsp=new DSPWrapper();
+ outFrame=new PCMFrame(samples);
+
+ float* left=new float[samples];
+ float* right=new float[samples];
+
+
+ // create queue with 500 frames. We want output to dsp(later)
+ // so we need a _FRAME_AUDIO_PCM type and we need
+ // for splay at least MP3FRAMESIZE
+ AudioFrameQueue* frameQueue;
+ if (queueType == _QUEUE_INT) {
+ frameQueue=new AudioFrameQueue(500,MP3FRAMESIZE,_FRAME_AUDIO_PCM);
+ }
+ if (queueType == _QUEUE_FLOAT) {
+ frameQueue=new AudioFrameQueue(100,MP3FRAMESIZE,_FRAME_AUDIO_FLOAT);
+ }
+
+
+ initDSP(dsp);
+ SplayDecoder* splay=new SplayDecoder();
+
+
+ //
+ // MpegAudioFrame has the ability to convert "raw" file
+ // data into mpeg I frames. These are "valid" frames,
+ // which means: header is ok, and the packet has the
+ // correct length. splay decodes these frames _at once_
+ // so we need no callbacks for the decoder.
+ MpegAudioFrame* frame=new MpegAudioFrame();
+
+
+ // Note: The inputbuffer must NOT NOT NOT be on the stack!
+ // correction: it should not be corrupted by allocation
+ // on the stack. This is true, if allocation+decoding
+ // or in the _same_ function.
+ unsigned char inputbuffer[INPUT_SIZE];
+
+
+ int cnt=0;
+ // we proceed until eof, or our "queue" is full.
+ while( (feof(file) == false) && (frameQueue->dataQueueCanWrite() == true) ) {
+
+ //
+ // This switch/case statement "partitions" the fileinput
+ // into mp3frames. We directly decode them to pcmFrames.
+ //
+
+ //
+ // There are three states. One is "I want Input, give me input"
+ // The other is "I have enough input, dont' bother me and let
+ // me do my work"
+ // The last ist "I have a frame here, take care of this, or
+ // I will continue with my work"
+
+ int state=frame->getState();
+ switch(state) {
+ case FRAME_NEED: {
+ int bytes=frame->canStore();
+ int read=fread(inputbuffer,1,bytes,file);
+ if (read != bytes) {
+ // read error. reset framer
+ frame->reset();
+ continue;
+ }
+ frame->store(inputbuffer,bytes);
+ break;
+ }
+ case FRAME_WORK:
+ frame->work();
+ break;
+ case FRAME_HAS:{
+ AudioFrame* emptyFrame= frameQueue->emptyQueueDequeue();
+ splay->decode(frame->outdata(),frame->len(),emptyFrame);
+ frameQueue->dataQueueEnqueue(emptyFrame);
+ cout << "storing decodec frame:"<<cnt<<endl;
+ cnt++;
+ break;
+ }
+ default:
+ cout << "unknown state in mpeg audio framing"<<endl;
+ exit(0);
+ }
+ }
+
+
+ //
+ // Fine we put all decoded frames in the buffer.
+ // Now we want to "stream" from this buffer.
+ //
+
+ //
+ // create our "local" stream
+ short int playbuf[INPUT_SIZE];
+
+ //
+ // we need to setup the dsp manually, when we do not play pcmFrames directly
+ //
+ if (queueType == _QUEUE_INT) {
+ AudioFrame* audioFrame=frameQueue->getCurrent();
+ dsp->audioSetup(audioFrame);
+ }
+
+ if (queueType == _QUEUE_FLOAT) {
+ AudioFrame* audioFrame=frameQueue->getCurrent();
+ dsp->audioSetup(audioFrame->getStereo(),16,
+ audioFrame->getSigned(),
+ audioFrame->getBigEndian(),
+ audioFrame->getFrequenceHZ());
+ outFrame->setFrameFormat(audioFrame->getStereo(),
+ audioFrame->getFrequenceHZ());
+ }
+
+
+
+ //
+ // read from stream demo:
+ //
+
+ while(frameQueue->getLen() > 0) {
+ int hasLen= frameQueue->getLen();
+
+ cout << "hasLen:"<<hasLen<<endl;
+ int hasRead;
+ if (hasLen < samples) {
+ samples=hasLen;
+ }
+
+
+
+ if (queueType == _QUEUE_INT) {
+ cout << "reading :"<<samples<<" data"<<endl;
+ hasRead=frameQueue->copy(outFrame->getData(),samples);
+ dsp->audioPlay((char*)outFrame->getData(),hasRead*sizeof(short int));
+ frameQueue->forwardStreamSingle(hasRead);
+ }
+
+
+ if (queueType == _QUEUE_FLOAT) {
+ int n;
+
+ hasRead=frameQueue->copy(left,right,samples);
+ frameQueue->forwardStreamDouble(hasRead);
+ n=hasRead;
+
+ /*
+ FloatFrame* floatFrame=( FloatFrame*) frameQueue->dataQueueDequeue();
+ float* left=floatFrame->getData();
+ n=floatFrame->getLen();
+ */
+
+ int i=0;
+ while(i<n) {
+ int val=(int)(32768.0*left[i]);
+ if (val > 32767) val=32767;
+ if (val < -32768) val=-32768;
+ dsp->audioPlay((char*)&val,2);
+
+ if (outFrame->getStereo()) {
+ val=(int)(32768.0*right[i]);
+ if (val > 32767) val=32767;
+ if (val < -32768) val=-32768;
+ dsp->audioPlay((char*)&val,2);
+ }
+
+ i++;
+ }
+
+ }
+ }
+
+
+ delete frameQueue;
+ delete splay;
+ delete frame;
+ delete dsp;
+ delete left;
+ delete right;
+ delete outFrame;
+ return(0);
+}
+