[xiph-commits] r18228 - trunk/spectrum

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Apr 11 18:40:12 PDT 2012


Author: xiphmont
Date: 2012-04-11 18:40:12 -0700 (Wed, 11 Apr 2012)
New Revision: 18228

Added:
   trunk/spectrum/io.c
   trunk/spectrum/io.h
Modified:
   trunk/spectrum/Makefile
   trunk/spectrum/main.c
   trunk/spectrum/plot.c
   trunk/spectrum/process.c
   trunk/spectrum/version.h
Log:
Split io and process functions in prep for adding waveform panel.


Modified: trunk/spectrum/Makefile
===================================================================
--- trunk/spectrum/Makefile	2012-04-11 22:22:12 UTC (rev 18227)
+++ trunk/spectrum/Makefile	2012-04-12 01:40:12 UTC (rev 18228)
@@ -25,8 +25,8 @@
 ETCDIR=/etc/spectrum
 MANDIR=$(PREFIX)/man
 
-SRC = main.c process.c panel.c plot.c
-OBJ = main.o process.o panel.o plot.o
+SRC = main.c process.c panel.c plot.c io.c
+OBJ = main.o process.o panel.o plot.o io.o
 GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0`
 
 all:	

Added: trunk/spectrum/io.c
===================================================================
--- trunk/spectrum/io.c	                        (rev 0)
+++ trunk/spectrum/io.c	2012-04-12 01:40:12 UTC (rev 18228)
@@ -0,0 +1,605 @@
+/*
+ *
+ *  gtk2 spectrum analyzer
+ *    
+ *      Copyright (C) 2004 Monty
+ *
+ *  This analyzer 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, or (at your option)
+ *  any later version.
+ *   
+ *  The analyzer 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 Postfish; see the file COPYING.  If not, write to the
+ *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ */
+
+#include "io.h"
+
+extern sig_atomic_t acc_loop;
+extern int blocksize;
+static int blockslice[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+
+float **blockbuffer=0;
+int blockbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+
+static unsigned char readbuffer[MAX_FILES][readbuffersize];
+static int readbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+static int readbufferptr[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+
+static FILE *f[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+static off_t offset[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+static off_t length[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+static off_t bytesleft[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+int seekable[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+int global_seekable=0;
+int total_ch=0;
+
+static int host_is_big_endian() {
+  int32_t pattern = 0xfeedface; /* deadbeef */
+  unsigned char *bytewise = (unsigned char *)&pattern;
+  if (bytewise[0] == 0xfe) return 1;
+  return 0;
+}
+
+/* Macros to read header data */
+#define READ_U32_LE(buf) \
+        (((buf)[3]<<24)|((buf)[2]<<16)|((buf)[1]<<8)|((buf)[0]&0xff))
+
+#define READ_U16_LE(buf) \
+        (((buf)[1]<<8)|((buf)[0]&0xff))
+
+#define READ_U32_BE(buf) \
+        (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|((buf)[3]&0xff))
+
+#define READ_U16_BE(buf) \
+        (((buf)[0]<<8)|((buf)[1]&0xff))
+
+double read_IEEE80(unsigned char *buf){
+  int s=buf[0]&0xff;
+  int e=((buf[0]&0x7f)<<8)|(buf[1]&0xff);
+  double f=((unsigned long)(buf[2]&0xff)<<24)|
+    ((buf[3]&0xff)<<16)|
+    ((buf[4]&0xff)<<8) |
+    (buf[5]&0xff);
+  
+  if(e==32767){
+    if(buf[2]&0x80)
+      return HUGE_VAL; /* Really NaN, but this won't happen in reality */
+    else{
+      if(s)
+	return -HUGE_VAL;
+      else
+	return HUGE_VAL;
+    }
+  }
+  
+  f=ldexp(f,32);
+  f+= ((buf[6]&0xff)<<24)|
+    ((buf[7]&0xff)<<16)|
+    ((buf[8]&0xff)<<8) |
+    (buf[9]&0xff);
+  
+  return ldexp(f, e-16446);
+}
+
+static int find_chunk(FILE *in, char *type, unsigned int *len, int endian){
+  unsigned int i;
+  unsigned char buf[8];
+
+  while(1){
+    if(fread(buf,1,8,in) <8)return 0;
+
+    if(endian)
+      *len = READ_U32_BE(buf+4);
+    else
+      *len = READ_U32_LE(buf+4);
+
+    if(memcmp(buf,type,4)){
+
+      if((*len) & 0x1)(*len)++;
+      
+      for(i=0;i<*len;i++)
+	if(fgetc(in)==EOF)return 0;
+
+    }else return 1;
+  }
+}
+
+int input_load(void){
+
+  int stdinp=0,i,fi;
+  if(inputs==0){
+    /* look at stdin... is it a file, pipe, tty...? */
+    if(isatty(STDIN_FILENO)){
+      fprintf(stderr,
+	      "Spectrum requires either an input file on the command line\n"
+	      "or stream data piped|redirected to stdin. spectrum -h will\n"
+	      "give more details.\n");
+      return 1;
+    }
+    stdinp=1;    /* file coming in via stdin */
+    inputname[0]=strdup("stdin");
+    inputs++;
+  }
+
+  for(fi=0;fi<inputs;fi++){
+
+    if(stdinp && fi==0){
+      int newfd=dup(STDIN_FILENO);
+      f[fi]=fdopen(newfd,"rb");
+    }else{
+      f[fi]=fopen(inputname[fi],"rb");
+    }
+    seekable[fi]=0;
+
+    /* Crappy! Use a lib to do this for pete's sake! */
+    if(f[fi]){
+      char headerid[12];
+      off_t filelength;
+	
+      /* parse header (well, sort of) and get file size */
+      seekable[fi]=(fseek(f[fi],0,SEEK_CUR)?0:1);
+
+      if(!seekable[fi]){
+	filelength=-1;
+      }else{
+	fseek(f[fi],0,SEEK_END);
+	filelength=ftello(f[fi]);
+	fseek(f[fi],0,SEEK_SET);
+	global_seekable=1;
+      }
+      
+      fread(headerid,1,12,f[fi]);
+      if(!strncmp(headerid,"RIFF",4) && !strncmp(headerid+8,"WAVE",4)){
+	unsigned int chunklen;
+      
+	if(find_chunk(f[fi],"fmt ",&chunklen,0)){
+	  int ltype;
+	  int lch;
+	  int lrate;
+	  int lbits;
+	  unsigned char *buf=alloca(chunklen);
+	
+	  fread(buf,1,chunklen,f[fi]);
+	
+	  ltype = READ_U16_LE(buf); 
+	  lch =   READ_U16_LE(buf+2); 
+	  lrate = READ_U32_LE(buf+4);
+	  lbits = READ_U16_LE(buf+14);
+
+          /* Add cooked WAVE_FORMAT_EXTENSIBLE support */
+          if(ltype == 65534){
+            int cbSize = READ_U16_LE(buf+16);
+            if(cbSize>=22)
+              ltype = READ_U16_LE(buf + 24); 
+	  }
+
+	  if(ltype!=1){
+            fprintf(stderr,"%s:\n\tWAVE file not PCM.\n",inputname[fi]);
+            return 1;
+	  }
+	      
+	  if(bits[fi]==-1)bits[fi]=lbits;
+	  if(channels[fi]==-1)channels[fi]=lch;
+	  if(signedp[fi]==-1){
+	    signedp[fi]=0;
+	    if(bits[fi]>8)signedp[fi]=1;
+	  }
+	  if(bigendian[fi]==-1)bigendian[fi]=0;
+	  if(rate[fi]==-1){
+	    if(lrate<4000 || lrate>192000){
+	      fprintf(stderr,"%s:\n\tSampling rate out of bounds\n",inputname[fi]);
+	      return 1;
+	    }
+	    rate[fi]=lrate;
+	  }
+
+	  if(find_chunk(f[fi],"data",&chunklen,0)){
+	    off_t pos=ftello(f[fi]);
+	    int bytes=(bits[fi]+7)/8;
+	    if(seekable[fi])
+	      filelength=
+		(filelength-pos)/
+		(channels[fi]*bytes)*
+		(channels[fi]*bytes)+pos;
+	    
+	    if(chunklen==0UL ||
+	       chunklen==0x7fffffffUL || 
+	       chunklen==0xffffffffUL){
+	      if(filelength==-1){
+		length[fi]=-1;
+		fprintf(stderr,"%s: Incomplete header; assuming stream.\n",inputname[fi]);
+	      }else{
+		length[fi]=(filelength-pos)/(channels[fi]*bytes);
+		fprintf(stderr,"%s: Incomplete header; using actual file size.\n",inputname[fi]);
+	      }
+	    }else if(filelength==-1 || chunklen+pos<=filelength){
+	      length[fi]=(chunklen/(channels[fi]*bytes));
+	      fprintf(stderr,"%s: Using declared file size (%ld).\n",
+		      inputname[fi],(long)length[fi]*channels[fi]*bytes);
+	      
+	    }else{
+	      
+	      length[fi]=(filelength-pos)/(channels[fi]*bytes);
+	      fprintf(stderr,"%s: File truncated; Using actual file size.\n",inputname[fi]);
+	    }
+	    offset[fi]=ftello(f[fi]);
+	  } else {
+	    fprintf(stderr,"%s: WAVE file has no \"data\" chunk following \"fmt \".\n",inputname[fi]);
+	    return 1;
+	  }
+	}else{
+	  fprintf(stderr,"%s: WAVE file has no \"fmt \" chunk.\n",inputname[fi]);
+	  return 1;
+	}
+      
+      }else if(!strncmp(headerid,"FORM",4) && !strncmp(headerid+8,"AIF",3)){
+	unsigned int len;
+	int aifc=0;
+	if(headerid[11]=='C')aifc=1;
+	unsigned char *buffer;
+	char buf2[8];
+	
+	int lch;
+	int lbits;
+	int lrate;
+	int bytes;
+	
+	/* look for COMM */
+	if(!find_chunk(f[fi], "COMM", &len,1)){
+	  fprintf(stderr,"%s: AIFF file has no \"COMM\" chunk.\n",inputname[fi]);
+	  return 1;
+	}
+	
+	if(len < 18 || (aifc && len<22)) {
+	  fprintf(stderr,"%s: AIFF COMM chunk is truncated.\n",inputname[fi]);
+	  return 1;
+	}
+	
+	buffer = alloca(len);
+	
+	if(fread(buffer,1,len,f[fi]) < len){
+	  fprintf(stderr, "%s: Unexpected EOF in reading AIFF header\n",inputname[fi]);
+	  return 1;
+	}
+	
+	lch = READ_U16_BE(buffer);
+	lbits = READ_U16_BE(buffer+6);
+	lrate = (int)read_IEEE80(buffer+8);
+      
+	if(bits[fi]==-1)bits[fi]=lbits;
+	bytes=(bits[fi]+7)/8;
+	if(signedp[fi]==-1)signedp[fi]=1;
+	if(rate[fi]==-1){
+	  if(lrate<4000 || lrate>192000){
+	    fprintf(stderr,"%s:\n\tSampling rate out of bounds\n",inputname[fi]);
+	    return 1;
+	  }
+	  rate[fi]=lrate;
+	}
+	if(channels[fi]==-1)channels[fi]=lch;
+	
+	if(bigendian[fi]==-1){
+	  if(aifc){
+	    if(!memcmp(buffer+18, "NONE", 4)) {
+	      bigendian[fi] = 1;
+	    }else if(!memcmp(buffer+18, "sowt", 4)) {
+	      bigendian[fi] = 0;
+	    }else{
+	      fprintf(stderr, "%s: Spectrum supports only linear PCM AIFF-C files.\n",inputname[fi]);
+	      return 1;
+	    }
+	  }else
+	    bigendian[fi] = 1;
+	}
+	if(!find_chunk(f[fi], "SSND", &len, 1)){
+	  fprintf(stderr,"%s: AIFF file has no \"SSND\" chunk.\n",inputname[fi]);
+	  return 1;
+	}
+	
+	if(fread(buf2,1,8,f[fi]) < 8){
+	  fprintf(stderr,"%s: Unexpected EOF reading AIFF header\n",inputname[fi]);
+	  return 1;
+	}
+	
+	{
+	  int loffset = READ_U32_BE(buf2);
+	  int lblocksize = READ_U32_BE(buf2+4);
+	  
+	  /* swallow some data */
+	  for(i=0;i<loffset;i++)
+	    if(fgetc(f[fi])==EOF)break;
+	  
+	  if( lblocksize == 0 && (bits[fi] == 24 || bits[fi] == 16 || bits[fi] == 8)){
+	    
+	    off_t pos=ftello(f[fi]);
+	    
+	    if(seekable[fi])
+	      filelength=
+		(filelength-pos)/
+		(channels[fi]*bytes)*
+		(channels[fi]*bytes)+pos;
+	  
+	    if(len==0UL ||
+	       len==0x7fffffffUL || 
+	       len==0xffffffffUL){
+	      if(filelength==-1){
+		length[fi]=-1;
+		fprintf(stderr,"%s: Incomplete header; assuming stream.\n",inputname[fi]);
+	      }else{
+		length[fi]=(filelength-pos)/(channels[fi]*bytes);
+		fprintf(stderr,"%s: Incomplete header; using actual file size.\n",inputname[fi]);
+	      }
+	    }else if(filelength==-1 || (len+pos-loffset-8)<=filelength){
+	      length[fi]=((len-loffset-8)/(channels[fi]*bytes));
+	      fprintf(stderr,"%s: Using declared file size.\n",inputname[fi]);
+	      
+	    }else{
+	      length[fi]=(filelength-pos)/(channels[fi]*bytes);
+	      fprintf(stderr,"%s: File truncated; Using actual file size.\n",inputname[fi]);
+	    }
+	    offset[fi]=pos;
+	  }else{
+	    fprintf(stderr, "%s: Spectrum supports only linear PCM AIFF-C files.\n",inputname[fi]);
+	    return 1;
+	  }
+	}
+      } else {
+	/* must be raw input */
+	fprintf(stderr,"Input has no header; assuming raw stream/file.\n");
+      
+	if(channels[fi]==-1)channels[fi]=1;
+	if(rate[fi]==-1)rate[fi]=44100;
+	if(bits[fi]==-1)bits[fi]=16;
+	if(signedp[fi]==-1)signedp[fi]=1;
+	if(bigendian[fi]==-1)bigendian[fi]=host_is_big_endian();
+      
+	offset[fi]=0;
+	length[fi]=-1;
+	if(seekable[fi])length[fi]=filelength/(channels[fi]*((bits[fi]+7)/8));
+	
+	memcpy(readbuffer[fi],headerid,12);
+	readbufferfill[fi]=12;
+	
+      }
+
+      /* select the full-block slice size: ~10fps */
+      blockslice[fi]=rate[fi]/10;
+      while(blockslice[fi]>blocksize/2)blockslice[fi]/=2;
+      total_ch += channels[fi];
+
+      if(length[fi]!=-1)
+	bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
+      
+    }else{
+      fprintf(stderr,"Unable to open %s: %s\n",inputname[fi],strerror(errno));
+      exit(1);
+    }
+  }
+
+  blockbuffer=malloc(total_ch*sizeof(*blockbuffer));
+  
+  for(i=0;i<total_ch;i++){
+    blockbuffer[i]=calloc(blocksize,sizeof(**blockbuffer));
+  }
+  
+  return 0;
+
+}
+
+/* Convert new data from readbuffer into the blockbuffers until the
+   blockbuffer is full */
+static void LBEconvert(void){
+  float scale=1./2147483648.;
+  int ch=0,fi;
+
+  for(fi=0;fi<inputs;fi++){
+    int bytes=(bits[fi]+7)/8;
+    int j;
+    int32_t xor=(signedp[fi]?0:0x80000000UL);
+    
+    int readlimit=(readbufferfill[fi]-readbufferptr[fi])/
+      channels[fi]/bytes*channels[fi]*bytes+readbufferptr[fi];
+
+    int bfill = blockbufferfill[fi];
+    int rptr = readbufferptr[fi];
+    unsigned char *rbuf = readbuffer[fi];
+
+    if(readlimit){
+      
+      switch(bytes){
+      case 1:
+	
+	while(bfill<blocksize && rptr<readlimit){
+	  for(j=ch;j<channels[fi]+ch;j++)
+	    blockbuffer[j][bfill]=((rbuf[rptr++]<<24)^xor)*scale;
+	  bfill++;
+	}
+	break;
+	
+      case 2:
+      
+	if(bigendian[fi]){
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr+1]<<16)| (rbuf[rptr]<<24))^xor)*scale;
+	      rptr+=2;
+	    }
+	    bfill++;
+	  }
+	}else{
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr]<<16)| (rbuf[rptr+1]<<24))^xor)*scale;
+	      rptr+=2;
+	    }
+	    bfill++;
+	  }
+	}
+	break;
+	
+      case 3:
+	
+	if(bigendian[fi]){
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr+2]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr]<<24))^xor)*scale;
+	      rptr+=3;
+	    }
+	    bfill++;
+	  }
+	}else{
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr+2]<<24))^xor)*scale;
+	      rptr+=3;
+	    }
+	    bfill++;
+	  }
+	}
+	break;
+      case 4:
+	
+	if(bigendian[fi]){
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr+3])|(rbuf[rptr+2]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr+3]<<24))^xor)*scale;
+	      rptr+=4;
+	    }
+	    bfill++;
+	  }
+	}else{
+	  while(bfill<blocksize && rptr<readlimit){
+	    for(j=ch;j<channels[fi]+ch;j++){
+	      blockbuffer[j][bfill]=
+		(((rbuf[rptr])|(rbuf[rptr+1]<<8)|(rbuf[rptr+2]<<16)|(rbuf[rptr+3]<<24))^xor)*scale;
+	      rptr+=4;
+	    }
+	    bfill++;
+	  }
+	}
+	break;
+      }
+    }
+    ch+=channels[fi];
+    blockbufferfill[fi]=bfill;
+    readbufferptr[fi]=rptr;    
+  }
+}
+
+/* when we return, the blockbuffer is full or we're at EOF */
+/* EOF cases: 
+     loop set: return EOF if all seekable streams have hit EOF
+     loop unset: return EOF if all streams have hit EOF
+   pad individual EOF streams out with zeroes until global EOF is hit  */
+
+int input_read(void){
+  int i,fi,ch=0;
+  int eof=1;
+  int notdone=1;
+
+  for(fi=0;fi<inputs;fi++){
+    
+    /* shift according to slice */
+    if(blockbufferfill[fi]==blocksize){
+      if(blockslice[fi]<blocksize){
+	for(i=0;i<channels[fi];i++)
+	  memmove(blockbuffer[i+ch],blockbuffer[i+ch]+blockslice[fi],
+		  (blocksize-blockslice[fi])*sizeof(**blockbuffer));
+	blockbufferfill[fi]-=blockslice[fi];
+      }else
+	blockbufferfill[fi]=0;
+    }
+    ch+=channels[fi];
+  }
+
+  while(notdone){
+    notdone=0;
+
+    /* if there's data left to be pulled out of a readbuffer, do that */
+    LBEconvert();
+    
+    ch=0;
+    for(fi=0;fi<inputs;fi++){
+      if(blockbufferfill[fi]!=blocksize){
+	
+	/* shift the read buffer before fill if there's a fractional
+	   frame in it */
+	if(readbufferptr[fi]!=readbufferfill[fi] && readbufferptr[fi]>0){
+	  memmove(readbuffer[fi],readbuffer[fi]+readbufferptr[fi],
+		  (readbufferfill[fi]-readbufferptr[fi])*sizeof(**readbuffer));
+	  readbufferfill[fi]-=readbufferptr[fi];
+	  readbufferptr[fi]=0;
+	}else{
+	  readbufferfill[fi]=0;
+	  readbufferptr[fi]=0;
+	}
+	
+	/* attempt to top off the readbuffer */
+	{
+	  long actually_readbytes=0,readbytes=readbuffersize-readbufferfill[fi];
+
+	  if(readbytes>0)
+	    actually_readbytes=fread(readbuffer[fi]+readbufferfill[fi],1,readbytes,f[fi]);
+	    
+	  if(actually_readbytes<0){
+	    fprintf(stderr,"Input read error from %s: %s\n",inputname[fi],strerror(errno));
+	  }else if (actually_readbytes==0){
+	    /* don't process any partially-filled blocks; the
+	       stairstep at the end could pollute results badly */
+	    
+	    memset(readbuffer[fi],0,readbuffersize);
+	    bytesleft[fi]=0;
+	    readbufferfill[fi]=0;
+	    readbufferptr[fi]=0;
+	    blockbufferfill[fi]=0;
+	  
+	  }else{
+	    bytesleft[fi]-=actually_readbytes;
+	    readbufferfill[fi]+=actually_readbytes;
+	    
+	    /* conditionally clear global EOF */
+	    if(acc_loop){
+	      if(seekable[fi])eof=0;
+	    }else{
+	      eof=0;
+	    }
+	    notdone=1;
+	  }
+	}
+      }
+      ch += channels[fi];
+    }
+  }
+  return eof;
+}
+
+int rewind_files(){
+  int fi;
+  for(fi=0;fi<inputs;fi++){
+    if(!seekable[fi])
+      return 1;
+  }
+
+  for(fi=0;fi<inputs;fi++){
+    blockbufferfill[fi]=0;
+    readbufferptr[fi]=0;
+    readbufferfill[fi]=0;
+    fseek(f[fi],offset[fi],SEEK_SET);
+    if(length[fi]!=-1)bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
+  }
+  return 0;
+}

Added: trunk/spectrum/io.h
===================================================================
--- trunk/spectrum/io.h	                        (rev 0)
+++ trunk/spectrum/io.h	2012-04-12 01:40:12 UTC (rev 18228)
@@ -0,0 +1,67 @@
+/*
+ *
+ *  gtk2 spectrum analyzer
+ *    
+ *      Copyright (C) 2004 Monty
+ *
+ *  This analyzer 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, or (at your option)
+ *  any later version.
+ *   
+ *  The analyzer 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 Postfish; see the file COPYING.  If not, write to the
+ *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ */
+
+#ifndef _IO_H_
+#define _IO_H_
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#define _ISOC99_SOURCE
+#define _FILE_OFFSET_BITS 64
+#define _REENTRANT 1
+#define __USE_GNU 1
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <string.h>
+#include <math.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#define MAX_FILES 16
+#define readbuffersize 8192
+
+extern int input_load(void);
+extern int input_read(void);
+extern int rewind_files(void);
+
+extern int inputs;
+extern int total_ch;
+extern int bits[MAX_FILES];
+extern int bigendian[MAX_FILES];
+extern int channels[MAX_FILES];
+extern int rate[MAX_FILES];
+extern int signedp[MAX_FILES];
+extern char *inputname[MAX_FILES];
+extern int seekable[MAX_FILES];
+extern int global_seekable;
+
+extern int blockbufferfill[MAX_FILES];
+extern float **blockbuffer;
+#endif
+

Modified: trunk/spectrum/main.c
===================================================================
--- trunk/spectrum/main.c	2012-04-11 22:22:12 UTC (rev 18227)
+++ trunk/spectrum/main.c	2012-04-12 01:40:12 UTC (rev 18228)
@@ -33,7 +33,6 @@
 char *version;
 char *inputname[MAX_FILES];
 int inputs=0;
-int total_ch=0;
 int blocksize = 131072;
 
 int bits[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};

Modified: trunk/spectrum/plot.c
===================================================================
--- trunk/spectrum/plot.c	2012-04-11 22:22:12 UTC (rev 18227)
+++ trunk/spectrum/plot.c	2012-04-12 01:40:12 UTC (rev 18228)
@@ -1,6 +1,6 @@
 /*
  *
- *  gt2 spectrum analyzer
+ *  gtk2 spectrum analyzer
  *    
  *      Copyright (C) 2004 Monty
  *
@@ -494,6 +494,14 @@
 
   }
   
+
+  {
+    GdkGCValues values;
+    //gdk_gc_get_values(p->drawgc,&values);
+    values.line_width=2;
+    gdk_gc_set_values(p->drawgc,&values,GDK_GC_LINE_WIDTH);
+  }
+
   /* draw actual data */
   if(p->ydata){
     int cho=0;
@@ -557,6 +565,15 @@
       cho+=p->ch[gi];
     }
   }
+
+  {
+    GdkGCValues values;
+    //gdk_gc_get_values(p->drawgc,&values);
+    values.line_width=1;
+    gdk_gc_set_values(p->drawgc,&values,GDK_GC_LINE_WIDTH);
+  }
+
+
 }
 
 static void draw_and_expose(GtkWidget *widget){

Modified: trunk/spectrum/process.c
===================================================================
--- trunk/spectrum/process.c	2012-04-11 22:22:12 UTC (rev 18227)
+++ trunk/spectrum/process.c	2012-04-12 01:40:12 UTC (rev 18228)
@@ -22,26 +22,12 @@
  */
 
 #include "analyzer.h"
+#include "io.h"
 
-static int blockslice[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
-
-static float **blockbuffer=0;
-static int blockbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-static float *window;
+static float *window=NULL;
 static float *freqbuffer=0;
 static fftwf_plan plan;
 
-static unsigned char readbuffer[MAX_FILES][readbuffersize];
-static int readbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-static int readbufferptr[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-
-static FILE *f[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-static off_t offset[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-static off_t length[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
-static off_t bytesleft[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
-int seekable[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-int global_seekable=0;
-
 pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 int feedback_increment=0;
 
@@ -78,586 +64,50 @@
 sig_atomic_t process_active=0;
 sig_atomic_t process_exit=0;
 
-static int host_is_big_endian() {
-  int32_t pattern = 0xfeedface; /* deadbeef */
-  unsigned char *bytewise = (unsigned char *)&pattern;
-  if (bytewise[0] == 0xfe) return 1;
-  return 0;
-}
+static void init_process(void){
+  int i;
+  if(window==NULL){
+    process_work=calloc(blocksize+2,sizeof(*process_work));
+    feedback_count=calloc(total_ch,sizeof(*feedback_count));
+    plot_data=calloc(total_ch,sizeof(*plot_data));
 
-/* Macros to read header data */
-#define READ_U32_LE(buf) \
-        (((buf)[3]<<24)|((buf)[2]<<16)|((buf)[1]<<8)|((buf)[0]&0xff))
+    feedback_acc=malloc(total_ch*sizeof(*feedback_acc));
+    feedback_max=malloc(total_ch*sizeof(*feedback_max));
+    feedback_instant=malloc(total_ch*sizeof(*feedback_instant));
+    floor_y=malloc(total_ch*sizeof(*floor_y));
+    floor_yy=malloc(total_ch*sizeof(*floor_yy));
 
-#define READ_U16_LE(buf) \
-        (((buf)[1]<<8)|((buf)[0]&0xff))
+    ph_acc=malloc(total_ch*sizeof(*ph_acc));
+    ph_max=malloc(total_ch*sizeof(*ph_max));
+    ph_instant=malloc(total_ch*sizeof(*ph_instant));
 
-#define READ_U32_BE(buf) \
-        (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|((buf)[3]&0xff))
+    freqbuffer=fftwf_malloc((blocksize+2)*sizeof(*freqbuffer));
+    for(i=0;i<total_ch;i++){
 
-#define READ_U16_BE(buf) \
-        (((buf)[0]<<8)|((buf)[1]&0xff))
+      floor_y[i]=calloc(blocksize/2+1,sizeof(**floor_y));
+      floor_yy[i]=calloc(blocksize/2+1,sizeof(**floor_yy));
+      feedback_acc[i]=calloc(blocksize/2+1,sizeof(**feedback_acc));
+      feedback_max[i]=calloc(blocksize/2+1,sizeof(**feedback_max));
+      feedback_instant[i]=calloc(blocksize/2+1,sizeof(**feedback_instant));
 
-double read_IEEE80(unsigned char *buf){
-  int s=buf[0]&0xff;
-  int e=((buf[0]&0x7f)<<8)|(buf[1]&0xff);
-  double f=((unsigned long)(buf[2]&0xff)<<24)|
-    ((buf[3]&0xff)<<16)|
-    ((buf[4]&0xff)<<8) |
-    (buf[5]&0xff);
-  
-  if(e==32767){
-    if(buf[2]&0x80)
-      return HUGE_VAL; /* Really NaN, but this won't happen in reality */
-    else{
-      if(s)
-	return -HUGE_VAL;
-      else
-	return HUGE_VAL;
+      ph_acc[i]=calloc(blocksize+2,sizeof(**ph_acc));
+      ph_max[i]=calloc(blocksize+2,sizeof(**ph_max));
+      ph_instant[i]=calloc(blocksize+2,sizeof(**ph_instant));
     }
-  }
-  
-  f=ldexp(f,32);
-  f+= ((buf[6]&0xff)<<24)|
-    ((buf[7]&0xff)<<16)|
-    ((buf[8]&0xff)<<8) |
-    (buf[9]&0xff);
-  
-  return ldexp(f, e-16446);
-}
 
-static int find_chunk(FILE *in, char *type, unsigned int *len, int endian){
-  unsigned int i;
-  unsigned char buf[8];
+    plan=fftwf_plan_dft_r2c_1d(blocksize,freqbuffer,
+                               (fftwf_complex *)freqbuffer,
+                               FFTW_ESTIMATE);
 
-  while(1){
-    if(fread(buf,1,8,in) <8)return 0;
-
-    if(endian)
-      *len = READ_U32_BE(buf+4);
-    else
-      *len = READ_U32_LE(buf+4);
-
-    if(memcmp(buf,type,4)){
-
-      if((*len) & 0x1)(*len)++;
-      
-      for(i=0;i<*len;i++)
-	if(fgetc(in)==EOF)return 0;
-
-    }else return 1;
+    /* construct proper window (sin^4 I'd think) */
+    window = calloc(blocksize,sizeof(*window));
+    for(i=0;i<blocksize;i++)window[i]=sin(M_PIl*i/blocksize);
+    for(i=0;i<blocksize;i++)window[i]*=window[i];
+    for(i=0;i<blocksize;i++)window[i]=sin(window[i]*M_PIl*.5);
+    for(i=0;i<blocksize;i++)window[i]*=window[i]/(blocksize/4)*.778;
   }
 }
 
-int input_load(void){
-
-  int stdinp=0,i,fi;
-  if(inputs==0){
-    /* look at stdin... is it a file, pipe, tty...? */
-    if(isatty(STDIN_FILENO)){
-      fprintf(stderr,
-	      "Spectrum requires either an input file on the command line\n"
-	      "or stream data piped|redirected to stdin. spectrum -h will\n"
-	      "give more details.\n");
-      return 1;
-    }
-    stdinp=1;    /* file coming in via stdin */
-    inputname[0]=strdup("stdin");
-    inputs++;
-  }
-
-  for(fi=0;fi<inputs;fi++){
-
-    if(stdinp && fi==0){
-      int newfd=dup(STDIN_FILENO);
-      f[fi]=fdopen(newfd,"rb");
-    }else{
-      f[fi]=fopen(inputname[fi],"rb");
-    }
-    seekable[fi]=0;
-
-    /* Crappy! Use a lib to do this for pete's sake! */
-    if(f[fi]){
-      char headerid[12];
-      off_t filelength;
-	
-      /* parse header (well, sort of) and get file size */
-      seekable[fi]=(fseek(f[fi],0,SEEK_CUR)?0:1);
-
-      if(!seekable[fi]){
-	filelength=-1;
-      }else{
-	fseek(f[fi],0,SEEK_END);
-	filelength=ftello(f[fi]);
-	fseek(f[fi],0,SEEK_SET);
-	global_seekable=1;
-      }
-      
-      fread(headerid,1,12,f[fi]);
-      if(!strncmp(headerid,"RIFF",4) && !strncmp(headerid+8,"WAVE",4)){
-	unsigned int chunklen;
-      
-	if(find_chunk(f[fi],"fmt ",&chunklen,0)){
-	  int ltype;
-	  int lch;
-	  int lrate;
-	  int lbits;
-	  unsigned char *buf=alloca(chunklen);
-	
-	  fread(buf,1,chunklen,f[fi]);
-	
-	  ltype = READ_U16_LE(buf); 
-	  lch =   READ_U16_LE(buf+2); 
-	  lrate = READ_U32_LE(buf+4);
-	  lbits = READ_U16_LE(buf+14);
-
-          /* Add cooked WAVE_FORMAT_EXTENSIBLE support */
-          if(ltype == 65534){
-            int cbSize = READ_U16_LE(buf+16);
-            if(cbSize>=22)
-              ltype = READ_U16_LE(buf + 24); 
-	  }
-
-	  if(ltype!=1){
-            fprintf(stderr,"%s:\n\tWAVE file not PCM.\n",inputname[fi]);
-            return 1;
-	  }
-	      
-	  if(bits[fi]==-1)bits[fi]=lbits;
-	  if(channels[fi]==-1)channels[fi]=lch;
-	  if(signedp[fi]==-1){
-	    signedp[fi]=0;
-	    if(bits[fi]>8)signedp[fi]=1;
-	  }
-	  if(bigendian[fi]==-1)bigendian[fi]=0;
-	  if(rate[fi]==-1){
-	    if(lrate<4000 || lrate>192000){
-	      fprintf(stderr,"%s:\n\tSampling rate out of bounds\n",inputname[fi]);
-	      return 1;
-	    }
-	    rate[fi]=lrate;
-	  }
-
-	  if(find_chunk(f[fi],"data",&chunklen,0)){
-	    off_t pos=ftello(f[fi]);
-	    int bytes=(bits[fi]+7)/8;
-	    if(seekable[fi])
-	      filelength=
-		(filelength-pos)/
-		(channels[fi]*bytes)*
-		(channels[fi]*bytes)+pos;
-	    
-	    if(chunklen==0UL ||
-	       chunklen==0x7fffffffUL || 
-	       chunklen==0xffffffffUL){
-	      if(filelength==-1){
-		length[fi]=-1;
-		fprintf(stderr,"%s: Incomplete header; assuming stream.\n",inputname[fi]);
-	      }else{
-		length[fi]=(filelength-pos)/(channels[fi]*bytes);
-		fprintf(stderr,"%s: Incomplete header; using actual file size.\n",inputname[fi]);
-	      }
-	    }else if(filelength==-1 || chunklen+pos<=filelength){
-	      length[fi]=(chunklen/(channels[fi]*bytes));
-	      fprintf(stderr,"%s: Using declared file size (%ld).\n",
-		      inputname[fi],(long)length[fi]*channels[fi]*bytes);
-	      
-	    }else{
-	      
-	      length[fi]=(filelength-pos)/(channels[fi]*bytes);
-	      fprintf(stderr,"%s: File truncated; Using actual file size.\n",inputname[fi]);
-	    }
-	    offset[fi]=ftello(f[fi]);
-	  } else {
-	    fprintf(stderr,"%s: WAVE file has no \"data\" chunk following \"fmt \".\n",inputname[fi]);
-	    return 1;
-	  }
-	}else{
-	  fprintf(stderr,"%s: WAVE file has no \"fmt \" chunk.\n",inputname[fi]);
-	  return 1;
-	}
-      
-      }else if(!strncmp(headerid,"FORM",4) && !strncmp(headerid+8,"AIF",3)){
-	unsigned int len;
-	int aifc=0;
-	if(headerid[11]=='C')aifc=1;
-	unsigned char *buffer;
-	char buf2[8];
-	
-	int lch;
-	int lbits;
-	int lrate;
-	int bytes;
-	
-	/* look for COMM */
-	if(!find_chunk(f[fi], "COMM", &len,1)){
-	  fprintf(stderr,"%s: AIFF file has no \"COMM\" chunk.\n",inputname[fi]);
-	  return 1;
-	}
-	
-	if(len < 18 || (aifc && len<22)) {
-	  fprintf(stderr,"%s: AIFF COMM chunk is truncated.\n",inputname[fi]);
-	  return 1;
-	}
-	
-	buffer = alloca(len);
-	
-	if(fread(buffer,1,len,f[fi]) < len){
-	  fprintf(stderr, "%s: Unexpected EOF in reading AIFF header\n",inputname[fi]);
-	  return 1;
-	}
-	
-	lch = READ_U16_BE(buffer);
-	lbits = READ_U16_BE(buffer+6);
-	lrate = (int)read_IEEE80(buffer+8);
-      
-	if(bits[fi]==-1)bits[fi]=lbits;
-	bytes=(bits[fi]+7)/8;
-	if(signedp[fi]==-1)signedp[fi]=1;
-	if(rate[fi]==-1){
-	  if(lrate<4000 || lrate>192000){
-	    fprintf(stderr,"%s:\n\tSampling rate out of bounds\n",inputname[fi]);
-	    return 1;
-	  }
-	  rate[fi]=lrate;
-	}
-	if(channels[fi]==-1)channels[fi]=lch;
-	
-	if(bigendian[fi]==-1){
-	  if(aifc){
-	    if(!memcmp(buffer+18, "NONE", 4)) {
-	      bigendian[fi] = 1;
-	    }else if(!memcmp(buffer+18, "sowt", 4)) {
-	      bigendian[fi] = 0;
-	    }else{
-	      fprintf(stderr, "%s: Spectrum supports only linear PCM AIFF-C files.\n",inputname[fi]);
-	      return 1;
-	    }
-	  }else
-	    bigendian[fi] = 1;
-	}
-	if(!find_chunk(f[fi], "SSND", &len, 1)){
-	  fprintf(stderr,"%s: AIFF file has no \"SSND\" chunk.\n",inputname[fi]);
-	  return 1;
-	}
-	
-	if(fread(buf2,1,8,f[fi]) < 8){
-	  fprintf(stderr,"%s: Unexpected EOF reading AIFF header\n",inputname[fi]);
-	  return 1;
-	}
-	
-	{
-	  int loffset = READ_U32_BE(buf2);
-	  int lblocksize = READ_U32_BE(buf2+4);
-	  
-	  /* swallow some data */
-	  for(i=0;i<loffset;i++)
-	    if(fgetc(f[fi])==EOF)break;
-	  
-	  if( lblocksize == 0 && (bits[fi] == 24 || bits[fi] == 16 || bits[fi] == 8)){
-	    
-	    off_t pos=ftello(f[fi]);
-	    
-	    if(seekable[fi])
-	      filelength=
-		(filelength-pos)/
-		(channels[fi]*bytes)*
-		(channels[fi]*bytes)+pos;
-	  
-	    if(len==0UL ||
-	       len==0x7fffffffUL || 
-	       len==0xffffffffUL){
-	      if(filelength==-1){
-		length[fi]=-1;
-		fprintf(stderr,"%s: Incomplete header; assuming stream.\n",inputname[fi]);
-	      }else{
-		length[fi]=(filelength-pos)/(channels[fi]*bytes);
-		fprintf(stderr,"%s: Incomplete header; using actual file size.\n",inputname[fi]);
-	      }
-	    }else if(filelength==-1 || (len+pos-loffset-8)<=filelength){
-	      length[fi]=((len-loffset-8)/(channels[fi]*bytes));
-	      fprintf(stderr,"%s: Using declared file size.\n",inputname[fi]);
-	      
-	    }else{
-	      length[fi]=(filelength-pos)/(channels[fi]*bytes);
-	      fprintf(stderr,"%s: File truncated; Using actual file size.\n",inputname[fi]);
-	    }
-	    offset[fi]=pos;
-	  }else{
-	    fprintf(stderr, "%s: Spectrum supports only linear PCM AIFF-C files.\n",inputname[fi]);
-	    return 1;
-	  }
-	}
-      } else {
-	/* must be raw input */
-	fprintf(stderr,"Input has no header; assuming raw stream/file.\n");
-      
-	if(channels[fi]==-1)channels[fi]=1;
-	if(rate[fi]==-1)rate[fi]=44100;
-	if(bits[fi]==-1)bits[fi]=16;
-	if(signedp[fi]==-1)signedp[fi]=1;
-	if(bigendian[fi]==-1)bigendian[fi]=host_is_big_endian();
-      
-	offset[fi]=0;
-	length[fi]=-1;
-	if(seekable[fi])length[fi]=filelength/(channels[fi]*((bits[fi]+7)/8));
-	
-	memcpy(readbuffer[fi],headerid,12);
-	readbufferfill[fi]=12;
-	
-      }
-
-      /* select the full-block slice size: ~10fps */
-      blockslice[fi]=rate[fi]/10;
-      while(blockslice[fi]>blocksize/2)blockslice[fi]/=2;
-      total_ch += channels[fi];
-
-      if(length[fi]!=-1)
-	bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
-      
-    }else{
-      fprintf(stderr,"Unable to open %s: %s\n",inputname[fi],strerror(errno));
-      exit(1);
-    }
-  }
-
-  blockbuffer=malloc(total_ch*sizeof(*blockbuffer));
-  process_work=calloc(blocksize+2,sizeof(*process_work));
-  feedback_count=calloc(total_ch,sizeof(*feedback_count));
-  plot_data=calloc(total_ch,sizeof(*plot_data));
-
-  feedback_acc=malloc(total_ch*sizeof(*feedback_acc));
-  feedback_max=malloc(total_ch*sizeof(*feedback_max));
-  feedback_instant=malloc(total_ch*sizeof(*feedback_instant));
-  floor_y=malloc(total_ch*sizeof(*floor_y));
-  floor_yy=malloc(total_ch*sizeof(*floor_yy));
-
-  ph_acc=malloc(total_ch*sizeof(*ph_acc));
-  ph_max=malloc(total_ch*sizeof(*ph_max));
-  ph_instant=malloc(total_ch*sizeof(*ph_instant));
-  
-  freqbuffer=fftwf_malloc((blocksize+2)*sizeof(*freqbuffer));
-  for(i=0;i<total_ch;i++){
-    blockbuffer[i]=calloc(blocksize,sizeof(**blockbuffer));
-
-    floor_y[i]=calloc(blocksize/2+1,sizeof(**floor_y));
-    floor_yy[i]=calloc(blocksize/2+1,sizeof(**floor_yy));
-    feedback_acc[i]=calloc(blocksize/2+1,sizeof(**feedback_acc));
-    feedback_max[i]=calloc(blocksize/2+1,sizeof(**feedback_max));
-    feedback_instant[i]=calloc(blocksize/2+1,sizeof(**feedback_instant));
-
-    ph_acc[i]=calloc(blocksize+2,sizeof(**ph_acc));
-    ph_max[i]=calloc(blocksize+2,sizeof(**ph_max));
-    ph_instant[i]=calloc(blocksize+2,sizeof(**ph_instant));
-  }
-  
-  plan=fftwf_plan_dft_r2c_1d(blocksize,freqbuffer,
-			     (fftwf_complex *)freqbuffer,
-			     FFTW_ESTIMATE);
-  
-  /* construct proper window (sin^4 I'd think) */
-  window = calloc(blocksize,sizeof(*window));
-  for(i=0;i<blocksize;i++)window[i]=sin(M_PIl*i/blocksize);
-  for(i=0;i<blocksize;i++)window[i]*=window[i];
-  for(i=0;i<blocksize;i++)window[i]=sin(window[i]*M_PIl*.5);
-  for(i=0;i<blocksize;i++)window[i]*=window[i]/(blocksize/4)*.778;
-    
-  return 0;
-
-}
-
-/* Convert new data from readbuffer into the blockbuffers until the
-   blockbuffer is full */
-static void LBEconvert(void){
-  float scale=1./2147483648.;
-  int ch=0,fi;
-
-  for(fi=0;fi<inputs;fi++){
-    int bytes=(bits[fi]+7)/8;
-    int j;
-    int32_t xor=(signedp[fi]?0:0x80000000UL);
-    
-    int readlimit=(readbufferfill[fi]-readbufferptr[fi])/
-      channels[fi]/bytes*channels[fi]*bytes+readbufferptr[fi];
-
-    int bfill = blockbufferfill[fi];
-    int rptr = readbufferptr[fi];
-    unsigned char *rbuf = readbuffer[fi];
-
-    if(readlimit){
-      
-      switch(bytes){
-      case 1:
-	
-	while(bfill<blocksize && rptr<readlimit){
-	  for(j=ch;j<channels[fi]+ch;j++)
-	    blockbuffer[j][bfill]=((rbuf[rptr++]<<24)^xor)*scale;
-	  bfill++;
-	}
-	break;
-	
-      case 2:
-      
-	if(bigendian[fi]){
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr+1]<<16)| (rbuf[rptr]<<24))^xor)*scale;
-	      rptr+=2;
-	    }
-	    bfill++;
-	  }
-	}else{
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr]<<16)| (rbuf[rptr+1]<<24))^xor)*scale;
-	      rptr+=2;
-	    }
-	    bfill++;
-	  }
-	}
-	break;
-	
-      case 3:
-	
-	if(bigendian[fi]){
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr+2]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr]<<24))^xor)*scale;
-	      rptr+=3;
-	    }
-	    bfill++;
-	  }
-	}else{
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr+2]<<24))^xor)*scale;
-	      rptr+=3;
-	    }
-	    bfill++;
-	  }
-	}
-	break;
-      case 4:
-	
-	if(bigendian[fi]){
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr+3])|(rbuf[rptr+2]<<8)|(rbuf[rptr+1]<<16)|(rbuf[rptr+3]<<24))^xor)*scale;
-	      rptr+=4;
-	    }
-	    bfill++;
-	  }
-	}else{
-	  while(bfill<blocksize && rptr<readlimit){
-	    for(j=ch;j<channels[fi]+ch;j++){
-	      blockbuffer[j][bfill]=
-		(((rbuf[rptr])|(rbuf[rptr+1]<<8)|(rbuf[rptr+2]<<16)|(rbuf[rptr+3]<<24))^xor)*scale;
-	      rptr+=4;
-	    }
-	    bfill++;
-	  }
-	}
-	break;
-      }
-    }
-    ch+=channels[fi];
-    blockbufferfill[fi]=bfill;
-    readbufferptr[fi]=rptr;    
-  }
-}
-
-/* when we return, the blockbuffer is full or we're at EOF */
-/* EOF cases: 
-     loop set: return EOF if all seekable streams have hit EOF
-     loop unset: return EOF if all streams have hit EOF
-   pad individual EOF streams out with zeroes until global EOF is hit  */
-
-static int input_read(void){
-  int i,fi,ch=0;
-  int eof=1;
-  int notdone=1;
-
-  for(fi=0;fi<inputs;fi++){
-    
-    /* shift according to slice */
-    if(blockbufferfill[fi]==blocksize){
-      if(blockslice[fi]<blocksize){
-	for(i=0;i<channels[fi];i++)
-	  memmove(blockbuffer[i+ch],blockbuffer[i+ch]+blockslice[fi],
-		  (blocksize-blockslice[fi])*sizeof(**blockbuffer));
-	blockbufferfill[fi]-=blockslice[fi];
-      }else
-	blockbufferfill[fi]=0;
-    }
-    ch+=channels[fi];
-  }
-
-  while(notdone){
-    notdone=0;
-
-    /* if there's data left to be pulled out of a readbuffer, do that */
-    LBEconvert();
-    
-    ch=0;
-    for(fi=0;fi<inputs;fi++){
-      if(blockbufferfill[fi]!=blocksize){
-	
-	/* shift the read buffer before fill if there's a fractional
-	   frame in it */
-	if(readbufferptr[fi]!=readbufferfill[fi] && readbufferptr[fi]>0){
-	  memmove(readbuffer[fi],readbuffer[fi]+readbufferptr[fi],
-		  (readbufferfill[fi]-readbufferptr[fi])*sizeof(**readbuffer));
-	  readbufferfill[fi]-=readbufferptr[fi];
-	  readbufferptr[fi]=0;
-	}else{
-	  readbufferfill[fi]=0;
-	  readbufferptr[fi]=0;
-	}
-	
-	/* attempt to top off the readbuffer */
-	{
-	  long actually_readbytes=0,readbytes=readbuffersize-readbufferfill[fi];
-
-	  if(readbytes>0)
-	    actually_readbytes=fread(readbuffer[fi]+readbufferfill[fi],1,readbytes,f[fi]);
-	    
-	  if(actually_readbytes<0){
-	    fprintf(stderr,"Input read error from %s: %s\n",inputname[fi],strerror(errno));
-	  }else if (actually_readbytes==0){
-	    /* don't process any partially-filled blocks; the
-	       stairstep at the end could pollute results badly */
-	    
-	    memset(readbuffer[fi],0,readbuffersize);
-	    bytesleft[fi]=0;
-	    readbufferfill[fi]=0;
-	    readbufferptr[fi]=0;
-	    blockbufferfill[fi]=0;
-	  
-	  }else{
-	    bytesleft[fi]-=actually_readbytes;
-	    readbufferfill[fi]+=actually_readbytes;
-	    
-	    /* conditionally clear global EOF */
-	    if(acc_loop){
-	      if(seekable[fi])eof=0;
-	    }else{
-	      eof=0;
-	    }
-	    notdone=1;
-	  }
-	}
-      }
-      ch += channels[fi];
-    }
-  }
-  return eof;
-}
-
 void rundata_clear(){
   int i,j;
   for(i=0;i<total_ch;i++){
@@ -683,18 +133,9 @@
   int eof_all;
   int noise=plot_noise;  
 
-  /* for each file, FOR SCIENCE! */
-  for(fi=0;fi<inputs;fi++){
-    if(acc_rewind && seekable[fi]){
+  if(acc_rewind)
+    rewind_files();
 
-      blockbufferfill[fi]=0;
-      readbufferptr[fi]=0;
-      readbufferfill[fi]=0;
-      fseek(f[fi],offset[fi],SEEK_SET);
-      if(length[fi]!=-1)bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
-    }
-  }
-
   eof_all=input_read();
 
   if(eof_all){
@@ -894,6 +335,8 @@
   float maxrate=-1.;
   float nyq;
 
+  init_process();
+
   for(fi=0;fi<inputs;fi++)
     if(rate[fi]>maxrate)maxrate=rate[fi];
   nyq=maxrate/2.;

Modified: trunk/spectrum/version.h
===================================================================
--- trunk/spectrum/version.h	2012-04-11 22:22:12 UTC (rev 18227)
+++ trunk/spectrum/version.h	2012-04-12 01:40:12 UTC (rev 18228)
@@ -1,2 +1,2 @@
 #define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Wed Apr 11 18:17:23 EDT 2012] */
+/* DO NOT EDIT: Automated versioning hack [Wed Apr 11 21:38:57 EDT 2012] */



More information about the commits mailing list