diff options
author | N.N <matju@users.sourceforge.net> | 2009-12-14 19:55:54 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@iem.at> | 2015-10-14 15:04:53 +0200 |
commit | c235f09fc5ef83827ac53375015f469cd7e13eec (patch) | |
tree | 4639e88e27e105709a2bbd6352cec17808fdc5c9 /src/ReadRaw.cpp | |
parent | 40194041a1efbf98c45185098e3795150a0128a4 (diff) |
import version 0.36
svn path=/trunk/externals/august/readanysf~/; revision=12836
Diffstat (limited to 'src/ReadRaw.cpp')
-rw-r--r-- | src/ReadRaw.cpp | 394 |
1 files changed, 0 insertions, 394 deletions
diff --git a/src/ReadRaw.cpp b/src/ReadRaw.cpp deleted file mode 100644 index 30d86e8..0000000 --- a/src/ReadRaw.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * readanysf~ external for pd. - * - * Copyright (C) 2003 August Black - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ReadRaw.cpp || code here was kindly 'borrowed' from d_soundfile.c from - * puredata source code by Miller Puckette - */ - -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <iostream> - -#include "ReadRaw.h" -#include <m_pd.h> - -//# define _F_FRACBITS 28 -//# define do_f_fromint(x) ((x) << _F_FRACBITS) -#define SCALE (1./(1024. * 1024. * 1024. * 2.)) - -using namespace std; - - - -int ambigendian(void) { - unsigned short s = 1; - unsigned char c = *(char *)(&s); - return (c==0); -} - - -static unsigned int swap4 (unsigned int n, int doit) { - if (doit) - return (((n & 0xff) << 24) | ((n & 0xff00) << 8) | - ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24)); - else - return (n); -} - -static unsigned short swap2 (unsigned int n, int doit) { - if (doit) - return (((n & 0xff) << 8) | ((n & 0xff00) >> 8)); - else - return (n); -} - -#define ULPOW2TO31 ((unsigned int)0x80000000) -#define DPOW2TO31 ((double)2147483648.0) /* 2^31 */ - -static double myUlongToDouble (unsigned int ul) { - double val; - if (ul & ULPOW2TO31) - val = DPOW2TO31 + (ul & (~ULPOW2TO31)); - else - val = ul; - return val; -} - -static double ieee_80_to_double (unsigned char *p) { - unsigned char sign; - short lexp = 0; - unsigned int mant1 = 0; - unsigned int mant0 = 0; - double val; - lexp = *p++; - lexp <<= 8; - lexp |= *p++; - sign = (lexp & 0x8000) ? 1 : 0; - lexp &= 0x7FFF; - mant1 = *p++; - mant1 <<= 8; - mant1 |= *p++; - mant1 <<= 8; - mant1 |= *p++; - mant1 <<= 8; - mant1 |= *p++; - mant0 = *p++; - mant0 <<= 8; - mant0 |= *p++; - mant0 <<= 8; - mant0 |= *p++; - mant0 <<= 8; - mant0 |= *p++; - if (mant1 == 0 && mant0 == 0 && lexp == 0 && sign == 0) - return 0.0; - else { - val = myUlongToDouble (mant0) * pow (2.0, -63.0); - val += myUlongToDouble (mant1) * pow (2.0, -31.0); - val *= pow (2.0, ((double) lexp) - 16383.0); - return sign ? -val : val; - } -} - -ReadRaw::ReadRaw () -{ - -} - -ReadRaw::ReadRaw (Input * input) { - //char file; - in = input; - bigendian = ambigendian(); - //bigendian = 0; -} - -ReadRaw::~ReadRaw () { - if (in != NULL) - in->Close (); -} - -bool ReadRaw::Initialize () { - char buf[128]; - int format, swap; - //long bytelimit = 0x7fffffff; - - - if (in == NULL) { - cout << "ReadRaw:: Input is NULL, this is bad, bailing...." << endl; - //shouldn't ever happen, but just checking - return false; //cout << "already opened, now closing file" << endl; - } - - int bytesread = in->Read (buf, READHDRSIZE); - - if (bytesread < 4) { - cout << "ReadRaw:: bytesread is < 4, this is bad, bailing...." << endl; - return false; - } - format = in->get_format (); // we know the format already - - - if (format == FORMAT_NEXT){ /* nextstep header */ - - //unsigned int param; - bigendian = 1; - swap = (bigendian != ambigendian()); - - if (bytesread < (int) sizeof (t_nextstep)) { - cout << "ReadRaw:: bytesread < sizeof(nextstep), this is bad, bailing...."<< endl; - return false; - } - num_channels = swap4 (((t_nextstep *) buf)->ns_nchans, swap); - format = swap4 (((t_nextstep *) buf)->ns_format, swap); - samplerate = (double) swap4( ((t_nextstep *) buf)->ns_sr, swap ); - - headersize = swap4 (((t_nextstep *) buf)->ns_onset, swap); - if (format == NS_FORMAT_LINEAR_16) - bytespersamp = 2; - else if (format == NS_FORMAT_LINEAR_24) - bytespersamp = 3; - else if (format == NS_FORMAT_FLOAT) - bytespersamp = 4; - else - return false; - - //bytelimit = 0x7fffffff; - - } else if (format == FORMAT_WAVE) { /* wave header */ - - /* This is awful. You have to skip over chunks, - * except that if one happens to be a "fmt" chunk, you want to - * find out the format from that one. The case where the - * "fmt" chunk comes after the audio isn't handled. */ - - bigendian = 0; - swap = (bigendian != ambigendian()); - - headersize = 12; - if (bytesread < 20) { - cout << "ReadRaw:: bytesread < 20, this is bad, bailing...." << endl; - return false; - } - /* First we guess a number of channels, etc., in case there's - * no "fmt" chunk to follow. */ - num_channels = 1; - bytespersamp = 2; - /* copy the first chunk header to beginnning of buffer. */ - memcpy (buf, buf + headersize, sizeof (t_wavechunk)); - - /* read chunks in loop until we get to the data chunk */ - while (strncmp (((t_wavechunk *) buf)->wc_id, "data", 4)) { - long chunksize = swap4 (((t_wavechunk *) buf)->wc_size, - swap), seekto = headersize + chunksize + 8, seekout; - - if (!strncmp(((t_wavechunk *) buf)->wc_id, "fmt ", 4)) { - long commblockonset = headersize + 8; - seekout = in->SeekSet ( commblockonset); - if (seekout != commblockonset) { - cout << "ReadRaw:: Seek prob, seekout != commblockonset" << endl; - return false; - } - if ( in->Read ( buf, sizeof (t_fmt) ) < (int) sizeof (t_fmt)) { - cout << "ReadRaw:: Read prob, read < sizeopf(t_fmt)" << endl; - return false; - } - - num_channels = swap2 (((t_fmt *) buf)->f_nchannels, swap); - samplerate = (double) swap2 (((t_fmt *) buf)->f_samplespersec, swap); - - int sampsize = swap2 (((t_fmt *) buf)->f_nbitspersample, swap); - - if (sampsize == 16) - bytespersamp = 2; - else if (sampsize == 24) - bytespersamp = 3; - else if (sampsize == 32) - bytespersamp = 4; - else { - cout << "ReadRaw:: bytespersamp is not supported, samplesize= "<< sampsize << endl; - //return false; - } - } - seekout = in->SeekSet ( seekto ); - if (seekout != seekto) { - cout << "ReadRaw:: Seek prob, seekout != seekto"<< endl; - return false; - } - if ( in->Read ( buf, sizeof (t_wavechunk) ) < (int) sizeof (t_wavechunk)) { - cout << "ReadRaw:: Read prob, read < sizeof(wavechunk)" << endl; - return false; - } - /* cout << "new chunk %c %c %c %c at %d", - * ((t_wavechunk *)buf)->wc_id[0], - * ((t_wavechunk *)buf)->wc_id[1], - * ((t_wavechunk *)buf)->wc_id[2], - * ((t_wavechunk *)buf)->wc_id[3], seekto); */ - headersize = seekto; - } - //bytelimit = swap4 (((t_wavechunk *) buf)->wc_size, swap); - headersize += 8; - } else { - /* AIFF. same as WAVE; actually predates it. Disgusting. */ - bigendian = 1; - swap = (bigendian != ambigendian()); - - headersize = 12; - if (bytesread < 20) - return false; - /* First we guess a number of channels, etc., in case there's - * no COMM block to follow. */ - num_channels = 1; - bytespersamp = 2; - /* copy the first chunk header to beginnning of buffer. */ - memcpy (buf, buf + headersize, sizeof (t_datachunk)); - /* read chunks in loop until we get to the data chunk */ - while (strncmp (((t_datachunk *) buf)->dc_id, "SSND", 4)) { - long chunksize = swap4 (((t_datachunk *) buf)->dc_size, - swap), seekto = headersize + chunksize + 8, seekout; - - if (!strncmp (((t_datachunk *) buf)->dc_id, "COMM", 4)) { - long commblockonset = headersize + 8; - seekout = in->SeekSet ( commblockonset ); - if (seekout != commblockonset) - return false; - if ( in->Read (buf, sizeof (t_comm)) < - (int) sizeof (t_comm)) - return false; - num_channels = swap2 (((t_comm *) buf)->c_nchannels, swap); - samplerate = ieee_80_to_double (((t_comm *) buf)->c_samprate); - - format = swap2 (((t_comm *) buf)->c_bitspersamp, swap); - if (format == 16) - bytespersamp = 2; - else if (format == 24) - bytespersamp = 3; - else - return false; - } - seekout = in->SeekSet ( seekto ); - if (seekout != seekto) - return false; - if ( in->Read (buf, sizeof (t_datachunk)) < - (int) sizeof (t_datachunk)) - return false; - headersize = seekto; - } - //bytelimit = swap4 (((t_datachunk *) buf)->dc_size, bigendian); - headersize += 8; - } - - //cout << "ReadRaw:: [%s] %1.0lf (Hz), %d chan(s), bps %d",in->get_filename(), - // samplerate, num_channels, bytespersamp); - //cout << " headersize = %d", headersize); - - long tmp = in->SeekEnd(0); // get filesize - if (tmp == -1) - post ("couldn't seek on file"); - lengthinseconds = (float) ((tmp - headersize) / bytespersamp / samplerate / num_channels); - - /* seek past header and any sample frames to skip */ - if ( ( in->SeekSet( headersize ) ) != -1 ) { - return true; - } else { - cout << "ReadRaw:: strange, wasn't able to seek on the file" << endl; - return false; - } -} - -bool ReadRaw::Rewind () { - if ( ( in->SeekSet( headersize ) ) != -1 ) - return true; - else - return false; -} - -int ReadRaw::Decode (float *buffer, int size) { - int ret, x = 0;; - int chunk = WAVCHUNKSIZE * bytespersamp * num_channels; - int bytesperframe = bytespersamp * num_channels; - unsigned char *sp; - float ftmp; - - if (chunk > size) - return 0; - ret = in->Read ( data, chunk ); - ret = ret * bytespersamp; - if (bytespersamp == 2) { - - for (int j = 0; j < ret; j += bytespersamp) { - sp = (unsigned char *) &data[j]; - if (bigendian) - ftmp = SCALE * ((sp[0] << 24) | (sp[1] << 16)); - else - ftmp = SCALE * ((sp[1] << 24) | (sp[0] << 16)); - buffer[x++] = ftmp; - //if (num_channels == 1) buffer[x++] = ftmp; - sp += bytesperframe; - } - - } else if (bytespersamp == 3) { - - for (int j = 0; j < ret; j += bytespersamp) { - sp = (unsigned char *) &data[j]; - if (bigendian) - ftmp = SCALE * ((sp[0] << 24) | (sp[1] << 16) | (sp[2] << 8)); - else - ftmp = SCALE * ((sp[2] << 24) | (sp[1] << 16) | (sp[0] << 8)); - buffer[x++] = ftmp; - //if (num_channels == 1) buffer[x++] = ftmp; - sp += bytesperframe; - } - - } else if (bytespersamp == 4) { - - for (int j = 0; j < ret; j += bytespersamp) { - sp = (unsigned char *) &data[j]; - if (bigendian) - ftmp = (float) ((sp[0] << 24) | (sp[1] << 16) | (sp[2] << 8) | sp[3]); - else - ftmp = (float) ((sp[3] << 24) | (sp[2] << 16) | (sp[1] << 8) | sp[0]); - buffer[x++] = ftmp; - //if (num_channels == 1) buffer[x++] = ftmp; - sp += bytesperframe; - } - - } - - return x / 2; //num_channels; //always two -} - - - -bool ReadRaw::PCM_seek (long frames) { - if (frames > (long) (lengthinseconds * samplerate)) - return false; - if ( in->SeekSet ( headersize + (frames * num_channels * bytespersamp ) ) != -1 ) - return true; - else { - cout << "ReadRaw:: fuck, no seeking!!" << endl; - return false; - } -} - -bool ReadRaw::TIME_seek (double seconds) { - long frames = (long) (seconds * samplerate); - return PCM_seek (frames); -} |