summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/frame/pcmFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/frame/pcmFrame.cpp')
-rw-r--r--mpeglib/lib/frame/pcmFrame.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/mpeglib/lib/frame/pcmFrame.cpp b/mpeglib/lib/frame/pcmFrame.cpp
new file mode 100644
index 00000000..24ab9792
--- /dev/null
+++ b/mpeglib/lib/frame/pcmFrame.cpp
@@ -0,0 +1,140 @@
+/*
+ pcm frame description.
+ 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 "pcmFrame.h"
+
+#include <iostream>
+
+using namespace std;
+
+#ifndef WORDS_BIGENDIAN
+// this is fast on INTEL, but maybe not work on other little
+// endian machines. (are there any?)
+#define convMacro(in,dtemp,tmp) \
+ in[0]*=SCALFACTOR; \
+ dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))+(in[0]); \
+ tmp = ((*(int *)&dtemp) - 0x80000000); \
+ in++; \
+ if(tmp>32767) { \
+ tmp=32767; \
+ } else if (tmp<-32768) { \
+ tmp =-0x8000; \
+ }
+
+#else /* big endian conversion: _AIX */
+static inline void convMacro(float*& in, double dtemp, int& tmp)
+{
+ in[0]*=SCALFACTOR;
+ tmp = (int)*in;
+ in++;
+ if(tmp>32767) {
+ tmp=32767;
+ } else if (tmp<-32768) {
+ tmp =-0x8000;
+ }
+ tmp = ((tmp & 0xff) << 8) | ((tmp >> 8) & 0xff);
+}
+#endif /* _AIX */
+
+
+PCMFrame::PCMFrame(int size) {
+ data=new short int[size];
+ len=0;
+ this->size=size;
+ // this format has a sampleSize of 16, signed, endian==machine
+ this->sampleSize=sizeof(short int)*8;
+ this->lSigned=true;
+ this->lBigEndian=AUDIOFRAME_BIGENDIAN;
+ setFrameType(_FRAME_AUDIO_PCM);
+}
+
+
+PCMFrame::~PCMFrame() {
+ delete [] data;
+}
+
+
+void PCMFrame::putFloatData(float* left,float* right,int copyLen) {
+ int destSize=0;
+ if (left != NULL) destSize++;
+ if (right != NULL) destSize++;
+ destSize*=copyLen;
+ if ((len+destSize) > size) {
+ cout << "cannot copy putFloatData L/R version . Does not fit"<<endl;
+ cout << "size:"<<size<<endl;
+ cout << "len:"<<len<<endl;
+ cout << "destSize:"<<destSize<<endl;
+ exit(0);
+ }
+ double dtemp;
+ int tmp;
+ int i=copyLen;
+ switch(getStereo()) {
+ case 1:
+ while(i > 0) {
+ convMacro(left,dtemp,tmp);
+ data[len++]=(short int)tmp;
+ convMacro(right,dtemp,tmp);
+ data[len++]=(short int)tmp;
+ i--;
+ }
+ break;
+ case 0:
+ if (left != NULL) {
+ int i=copyLen;
+ while(i > 0) {
+ convMacro(left,dtemp,tmp);
+ data[len++]=(short int)tmp;
+ i--;
+ // right channel empty
+ len++;
+ }
+ }
+ if (right != NULL) {
+ int i=copyLen;
+ len=len-destSize;
+ while(i > 0) {
+ // select right channel
+ len++;
+ convMacro(right,dtemp,tmp);
+ data[len++]=(short int)tmp;
+ i--;
+ // left channel already copied
+ }
+ }
+ break;
+ default:
+ cout << "unknown stereo value in pcmFrame"<<endl;
+ exit(0);
+ }
+}
+
+void PCMFrame::putFloatData(float* in,int lenCopy) {
+
+ if ((len+lenCopy) > size) {
+ cout << "cannot copy putFloatData. Does not fit"<<endl;
+ exit(0);
+ }
+ double dtemp;
+ int tmp;
+ while(lenCopy > 0) {
+ convMacro(in,dtemp,tmp);
+ data[len++]=(short int)tmp;
+ lenCopy--;
+ }
+
+}
+
+
+