summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/splay/mpegAudioFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/splay/mpegAudioFrame.cpp')
-rw-r--r--mpeglib/lib/splay/mpegAudioFrame.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/mpeglib/lib/splay/mpegAudioFrame.cpp b/mpeglib/lib/splay/mpegAudioFrame.cpp
new file mode 100644
index 00000000..807a23a6
--- /dev/null
+++ b/mpeglib/lib/splay/mpegAudioFrame.cpp
@@ -0,0 +1,200 @@
+/*
+ converts raw mpeg audio stream data into mpeg I encoded audio frames/packets
+ 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 "mpegAudioFrame.h"
+
+#define MPEGAUDIOFRAMESIZE 4096
+
+#define FRAME_SYNC 0
+#define FRAME_CHECK_HEADER_1 1
+#define FRAME_CHECK_HEADER_2 2
+
+#include <iostream>
+
+using namespace std;
+
+MpegAudioFrame::MpegAudioFrame():Framer(MPEGAUDIOFRAMESIZE) {
+ mpegAudioHeader=new MpegAudioHeader();
+}
+
+
+MpegAudioFrame::~MpegAudioFrame() {
+ delete mpegAudioHeader;
+}
+
+
+void MpegAudioFrame::unsync(RawDataBuffer* store,int ) {
+ // invalidate header in buffer
+ unsigned char* start=store->ptr();
+ start[0]=0x0;
+ start[1]=0x0;
+ store->setpos(0);
+ find_frame_state=FRAME_SYNC;
+ framesize=0;
+}
+
+
+/**
+ here we parse byte by byte the raw input, first
+ we search for the magic bytes: 0xfffx, then
+ we read the remaining 2 bytes for the header,
+ check if they are "wrong" in a mpeg I audio special way.
+ If everything is fine, we continue with the next state.
+
+ Note: we can be sure here, that the "store" can at least
+ store 4 bytes.
+*/
+int MpegAudioFrame::find_frame(RawDataBuffer* input_buffer,
+ RawDataBuffer* store_buffer) {
+ unsigned char* store=store_buffer->current();
+ int back=false;
+
+ if (find_frame_state == FRAME_SYNC) {
+ if (store_buffer->pos() != 0) {
+ cout << "store buffer not at beginning MpegAudioFrame::find_frame"<<endl;
+ cout << "current state requires this"<<endl;
+ exit(0);
+ }
+ }
+
+ while(input_buffer->eof()==false) {
+ // search for sync bytes
+ unsigned char* input=input_buffer->current();
+ if (find_frame_state == FRAME_SYNC) {
+ while(input_buffer->eof() == false) {
+ input=input_buffer->current();
+ // shift
+ store[0]=store[1];
+ store[1]=input[0];
+ input_buffer->inc();
+
+ if (store[0] != 0xff) {
+ continue;
+ }
+ // upper 4 bit are syncword, except bit one
+ // which is layer 2.5 indicator.
+ if ( (store[1] & 0xe0) != 0xe0) {
+ continue;
+ }
+
+ // found header, now check if other info is ok, too.
+ store_buffer->setpos(2);
+ find_frame_state=FRAME_CHECK_HEADER_1;
+ break;
+ }
+ // back to "main loop"
+ continue;
+ }
+ // ok, try to read two other bytes and then validate the header
+ if (find_frame_state == FRAME_CHECK_HEADER_1) {
+ store[2]=input[0];
+ input_buffer->inc();
+ find_frame_state=FRAME_CHECK_HEADER_2;
+ // back to main loop
+ continue;
+ }
+ if (find_frame_state == FRAME_CHECK_HEADER_2) {
+ store[3]=input[0];
+ input_buffer->inc();
+ }
+
+ // ok, read 4 header bytes. Now check the validity of the
+ // header.
+ int lHeaderOk;
+ lHeaderOk=mpegAudioHeader->parseHeader(store);
+ if (lHeaderOk == false) {
+ find_frame_state=FRAME_SYNC;
+ store_buffer->setpos(0);
+ // go back to "sync for frame"
+ continue;
+ }
+ framesize=mpegAudioHeader->getFramesize();
+ // if framesize > max mepg framsize its an error
+ if (framesize+4 >= store_buffer->size()) {
+ find_frame_state=FRAME_SYNC;
+ store_buffer->setpos(0);
+ // go back to "sync for frame"
+ continue;
+ }
+ // don't allow stupid framesizes:
+ if (framesize <= 4) {
+ find_frame_state=FRAME_SYNC;
+ store_buffer->setpos(0);
+ continue;
+ }
+ // yup! found valid header. forward states
+ store_buffer->setpos(4);
+ back=true;
+ break;
+ }
+ return back;
+}
+
+
+/**
+ here we read data until len=framesize.
+ Then we go to the HAS_FRAME state.
+*/
+int MpegAudioFrame::read_frame(RawDataBuffer* input_buffer,
+ RawDataBuffer* store_buffer) {
+ unsigned char* store=store_buffer->current();
+
+ while(input_buffer->eof()==false) {
+ int has=store_buffer->pos();
+ int need=framesize-has;
+ if(need == 0) {
+ // yup! frame fully read. forward states.
+ // go to end state for main_state.
+ return true;
+ }
+ // try to do a memcpy for speed.
+ int can=input_buffer->untilend();
+ if(can > need) {
+ can=need;
+ }
+ unsigned char* input=input_buffer->current();
+ memcpy(store,input,can);
+ store_buffer->inc(can);
+ input_buffer->inc(can);
+ }
+ int need=framesize-store_buffer->pos();
+
+ if(need == 0) {
+ // yup! frame fully read. forward states.
+ // go to end state for main_state.
+ return true;
+ }
+ return false;
+}
+
+
+
+void MpegAudioFrame::printPrivateStates() {
+ cout << "MpegAudioFrame::printPrivateStates"<<endl;
+ switch(find_frame_state) {
+ case FRAME_SYNC:
+ cout << "frame_state: FRAME_SYNC"<<endl;
+ break;
+ case FRAME_CHECK_HEADER_1:
+ cout << "frame_state: FRAME_CHECK_HEADER_1"<<endl;
+ break;
+ case FRAME_CHECK_HEADER_2:
+ cout << "frame_state: FRAME_CHECK_HEADER_2"<<endl;
+ break;
+ default:
+ cout << "unknown illegal frame_state:"<<find_frame_state<<endl;
+ }
+
+
+}
+