[xiph-cvs] cvs commit: postfish input.c mainpanel.h readout.h
Monty
xiphmont at xiph.org
Sat Oct 11 17:44:15 PDT 2003
xiphmont 03/10/11 20:44:15
Added: . input.c mainpanel.h readout.h
Log:
catch up local copy with CVS
Revision Changes Path
1.1 postfish/input.c
Index: input.c
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2003 Monty
*
* Postfish 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.
*
* Postfish 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.
*
*
*/
tatic off_t Acursor=0;
static off_t Bcursor=-1;
static long T=-1;
static off_t cursor=0;
static int rate;
static sig_atomic_t loop_active;
tatic typedef struct {
FILE *f;
off_t begin;
off_t end;
off_t data;
} file_entry;
tatic file_entry *file_list=NULL;
static int file_entries=0;
static int current_file_entry_number=-1;
static file_entry *current_file_entry=NULL;
static int seekable=0;
int input_seekablep(void){
return seekable;
}
int input_rate_get(void){
return rate;
}
void input_cursorA_set(off_t c){
pthread_mutex_lock(&master_mutex);
cursorA=c;
pthread_mutex_unlock(&master_mutex);
}
void input_cursorB_set(off_t c){
pthread_mutex_lock(&master_mutex);
cursorB=c;
pthread_mutex_unlock(&master_mutex);
}
void input_cursor_set(off_t cr){
pthread_mutex_lock(&master_mutex);
cursor=c;
pthread_mutex_unlock(&master_mutex);
}
off_t input_cursor_get(void){
off_t ret;
pthread_mutex_lock(&master_mutex);
ret=cursor;
pthread_mutex_unlock(&master_mutex);
return ret;
}
off_t input_time_to_cursor(char *t){
char temp[14];
char *c;
int hd;
int s;
int m;
int h;
strncpy(temp,t,14);
/* hundredths */
c=strchr(temp,'.');
if(c){
*c=0;
hd=atoi(c+1);
if(hd>99)hd=99;
if(hd<0)hd=0;
}else
hd=0;
/* seconds */
c=strrchr(temp,':');
if(c){
*c=0;
s=atoi(c+1);
if(s>59)s=59;
if(s<0)s=0;
}else
s=0;
/* minutes */
c=strrchr(temp,':');
if(c){
*c=0;
m=atoi(c+1);
if(m>59)m=59;
if(m<0)m=0;
}else
m=0;
/* hours */
c=strrchr(temp,':');
if(c){
*c=0;
h=atoi(c+1);
if(h>9999)h=9999;
if(h<0)h=0;
}else
h=0;
return (off_t)hd + (off_t)s*100 + (off_t)m*60*100 + (off_t)h*60*60*100;
}
void time_fix(char *buffer){
if(buffer[0]=='0')buffer[0]=' ';
if(!strncmp(buffer," 0",2))buffer[1]=' ';
if(!strncmp(buffer," 0",3))buffer[2]=' ';
if(!strncmp(buffer," 0",4))buffer[3]=' ';
if(!strncmp(buffer," :0",6))buffer[5]=' ';
if(!strncmp(buffer," : 0",7))buffer[6]=' ';
if(buffer[0]!=' ' && buffer[1]==' ')buffer[1]='0';
if(buffer[1]!=' ' && buffer[2]==' ')buffer[2]='0';
if(buffer[2]!=' ' && buffer[3]==' ')buffer[3]='0';
if(buffer[3]!=' ' && buffer[5]==' ')buffer[5]='0';
if(buffer[5]!=' ' && buffer[6]==' ')buffer[6]='0';
}
void input_cursor_to_time(off_t cursor,char *t){
char
int h=cursor/60/60/100,m,s,hd;
cursor%=(off_t)60*60*100;
m=cursor/60/100;
cursor%=(off_t)60*100;
s=cursor/100;
m=cursor%100;
if(h>9999)h=9999;
sprintf(t,"%04d:%02d:%02d.%02d",h,m,s,hd);
time_fix(t);
}
<p>int aseek(off_t pos){
int i;
if(pos<0)pos=0;
if(!seekable){
current_file_entry=file_list;
current_file_entry_number=0;
return -1;
}
pthread_mutex_lock(&master_mutex);
for(i=0;i<file_entries;i++){
current_file_entry=file_list+i;
current_file_entry_number=i;
if(current_file_entry->begin<=pos && current_file_entry->end>pos){
fseeko(current_file_entry->f,
pos-current_file_entry->begin+current_file_entry->data,
SEEK_SET);
cursor=pos;
pthread_mutex_unlock(&master_mutex);
return 0;
}
}
i--;
pos=current_file_entry->end;
fseeko(current_file_entry->f,
pos-current_file_entry->begin+current_file_entry->data,
SEEK_SET);
cursor=pos;
pthread_mutex_unlock(&master_mutex);
return(0);
}
int aread(double **buf){
int read_b=0,i,j,k;
int toread_b=block*ch*inbytes;
unsigned char *readbuf;
double M,S;
pthread_mutex_lock(&master_mutex);
/* the non-streaming case */
if(Bcursor<0 &&
cursor>=current_file_entry->end &&
current_file_entry->end!=-1){
pthread_mutex_unlock(&master_mutex);
return -1; /* EOF */
}
/* the streaming case */
if(feof(current_file_entry->f) &&
current_file_entry_number+1>=file_entries){
pthread_mutex_unlock(&master_mutex);
return -1;
}
if(primed){
for(j=0;j<ch;j++)
memmove(buf[j],buf[j]+block/2,sizeof(**buf)*block/2);
toread_b/=2;
}
readbuf=alloca(toread_b);
while(toread_b){
off_t ret;
off_t read_this_loop=current_file_entry->end-cursor;
if(read_this_loop>toread_b)read_this_loop=toread_b;
ret=fread(readbuf+read_b,1,read_this_loop,current_file_entry->f);
if(ret>0){
read_b+=ret;
toread_b-=ret;
cursor+=ret;
}else{
if(current_file_entry_number+1>=file_entries){
memset(readbuf+read_b,0,toread_b);
read_b+=toread_b;
toread_b=0;
}
}
if(Bcursor!=-1 && cursor>=Bcursor){
if(loop_flag)
aseek(Acursor);
else{
pthread_mutex_unlock(&master_mutex);
return(-1);
}
}else if(cursor>=current_file_entry->end){
if(current_file_entry_number+1<file_entries){
current_file_entry_number++;
current_file_entry++;
fseeko(current_file_entry->f,current_file_entry->data,SEEK_SET);
}
}
}
k=0;
for(i=(primed?block/2:0);i<block;i++){
for(j=0;j<ch;j++){
int val=0;
switch(inbytes){
case 1:
val=(readbuf[k]<<24);
break;
case 2:
val=(readbuf[k]<<16)|(readbuf[k+1]<<24);
break;
case 3:
val=(readbuf[k]<<8)|(readbuf[k+1]<<16)|(readbuf[k+2]<<24);
break;
case 4:
val=(readbuf[k])|(readbuf[k+1]<<8)|(readbuf[k+2]<<16)|(readbuf[k+3]<<24);
break;
}
if(signp)
buf[j][i]=val*4.6566128730e-10;
else
buf[j][i]=(val^0x80000000UL)*4.6566128730e-10;
k+=inbytes;
}
if(ch==2){
M=(buf[0][i]+buf[1][i])*.5;
S=(buf[0][i]-buf[1][i])*.5;
buf[0][i]=M;
buf[1][i]=S;
}
}
primed=1;
pthread_mutex_unlock(&master_mutex);
return 0;
}
void PutNumLE(long num,FILE *f,int bytes){
int i=0;
while(bytes--){
fputc((num>>(i<<3))&0xff,f);
i++;
}
}
void WriteWav(FILE *f,long channels,long rate,long bits,long duration){
if(ftell(f)>0)
if(fseek(f,0,SEEK_SET))
return;
fprintf(f,"RIFF");
PutNumLE(duration+44-8,f,4);
fprintf(f,"WAVEfmt ");
PutNumLE(16,f,4);
PutNumLE(1,f,2);
PutNumLE(channels,f,2);
PutNumLE(rate,f,4);
PutNumLE(rate*channels*((bits-1)/8+1),f,4);
PutNumLE(((bits-1)/8+1)*channels,f,2);
PutNumLE(bits,f,2);
fprintf(f,"data");
PutNumLE(duration,f,4);
}
int isachr(FILE *f){
struct stat s;
if(!fstat(fileno(f),&s))
if(S_ISCHR(s.st_mode)) return 1;
return 0;
}
/* playback must be halted to change blocksize. */
void *playback_thread(void *dummy){
FILE *playback_fd=NULL;
int i,j,k;
int format=AFMT_S16_NE;
int channels=ch;
int irate=rate;
unsigned char *audiobuf;
int audiobufsize;
int ret,fd;
double **buf;
double **work;
double **save;
int bigendianp=0;
double scale;
int last=0;
off_t count=0;
pthread_mutex_lock(&master_mutex);
//block=wc.block_a;
//scale=2./block;
pthread_mutex_unlock(&master_mutex);
if(outfileno==-1){
playback_fd=fopen("/dev/dsp","wb");
}else{
playback_fd=fdopen(dup(outfileno),"wb");
}
if(!playback_fd){
playback_active=0;
playback_exit=0;
return NULL;
}
/* is this file a block device? */
if(isachr(playback_fd)){
int fragment=0x7fff0008;
fd=fileno(playback_fd);
/* try to lower the DSP delay; this ioctl may fail gracefully */
ret=ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&fragment);
if(ret){
fprintf(stderr,"Could not set DSP fragment size; continuing.\n");
}
ret=ioctl(fd,SNDCTL_DSP_SETFMT,&format);
if(ret || format!=AFMT_S16_NE){
fprintf(stderr,"Could not set AFMT_S16_NE playback\n");
exit(1);
}
ret=ioctl(fd,SNDCTL_DSP_CHANNELS,&channels);
if(ret || channels!=ch){
fprintf(stderr,"Could not set %d channel playback\n",ch);
exit(1);
}
ret=ioctl(fd,SNDCTL_DSP_SPEED,&irate);
if(ret || irate!=rate){
fprintf(stderr,"Could not set %dHz playback\n",44100);
exit(1);
}
if(AFMT_S16_NE==AFMT_S16_BE)bigendianp=1;
}else{
WriteWav(playback_fd,ch,rate,outbytes*8,-1);
}
buf=alloca(sizeof(*buf)*ch);
work=alloca(sizeof(*work)*ch);
save=alloca(sizeof(*save)*ch);
for(i=0;i<ch;i++){
buf[i]=alloca(sizeof(**buf)*block);
work[i]=alloca(sizeof(**work)*block);
save[i]=alloca(sizeof(**save)*block/2);
memset(save[i],0,sizeof(**save)*block/2);
}
audiobufsize=block/2*ch*outbytes;
audiobuf=alloca(audiobufsize);
aseek(cursor);
primed=0;
while(1){
if(playback_exit)break;
/* get data */
if(aread(buf))break;
<p> /* processing goes here */
<p> /* Back to L/R if stereo */
if(ch==2){
for(i=0;i<block;i++){
double L=(buf[0][i]+buf[1][i])*.5;
double R=(buf[0][i]-buf[1][i])*.5;
buf[0][i]=L;
buf[1][i]=R;
}
}
/* final limiting */
for(k=0,i=0;i<block/2;i++){
for(j=0;j<ch;j++){
int val=rint(buf[j][i]*32767.);
if(val>32767)val=32767;
if(val<-32768)val=-32768;
if(bigendianp){
audiobuf[k++]=val>>8;
audiobuf[k++]=val;
}else{
audiobuf[k++]=val;
audiobuf[k++]=val>>8;
}
}
}
{
struct timeval tv;
long foo;
gettimeofday(&tv,NULL);
foo=tv.tv_sec*10+tv.tv_usec/100000;
if(last!=foo)
write(eventpipe[1],"",1);
last=foo;
}
count+=fwrite(audiobuf,1,audiobufsize,playback_fd);
}
if(isachr(playback_fd)){
fd=fileno(playback_fd);
ret=ioctl(fd,SNDCTL_DSP_RESET);
}else{
WriteWav(playback_fd,ch,rate,outbytes*8,count);
}
fclose(playback_fd);
playback_active=0;
playback_exit=0;
write(eventpipe[1],"",1);
return(NULL);
}
int main(int argc, char **argv){
off_t total=0;
int i,j;
int configfd=-1;
int stdinp=0;
char *fname="stdin";
/* parse command line and open all the input files */
if(argc==1){
/* look at stdin... is it a file, pipe, tty...? */
if(isatty(STDIN_FILENO)){
fprintf(stderr,
"Postfish requires input either as a list of contiguous WAV\n"
"files on the command line, or WAV data piped|redirected to\n"
"stdin.\n");
exit(1);
}
stdinp=1; /* file coming in via stdin */
file_entries=1;
}else
file_entries=argc-1;
file_list=calloc(file_entries,sizeof(file_entry));
for(i=1;i<=file_entries;i++){
FILE *f;
if(stdinp){
int newfd=dup(STDIN_FILENO);
f=fdopen(newfd,"rb");
}else{
f=fopen(argv[i],"rb");
fname=argv[i];
}
if(f){
unsigned char buffer[81];
off_t filelength;
int datap=0;
int fmtp=0;
file_list[i-1].f=f;
/* parse header (well, sort of) and get file size */
seekable=(fseek(f,0,SEEK_CUR)?0:1);
if(!seekable){
filelength=-1;
}else{
fseek(f,0,SEEK_END);
filelength=ftello(f);
fseek(f,0,SEEK_SET);
}
fread(buffer,1,12,f);
if(strncmp(buffer,"RIFF",4) || strncmp(buffer+8,"WAVE",4)){
fprintf(stderr,"%s: Not a WAVE file.\n",fname);
exit(1);
}
while(fread(buffer,1,8,f)==8){
unsigned long chunklen=
buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
if(!strncmp(buffer,"fmt ",4)){
int ltype;
int lch;
int lrate;
int lbits;
if(chunklen>80){
fprintf(stderr,"%s: WAVE file fmt chunk too large to parse.\n",fname);
exit(1);
}
fread(buffer,1,chunklen,f);
ltype=buffer[0] |(buffer[1]<<8);
lch= buffer[2] |(buffer[3]<<8);
lrate=buffer[4] |(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
lbits=buffer[14]|(buffer[15]<<8);
if(ltype!=1){
fprintf(stderr,"%s: WAVE file not PCM.\n",fname);
exit(1);
}
if(i==1){
ch=lch;
rate=lrate;
inbytes=lbits/8;
if(inbytes>1)signp=1;
}else{
if(ch!=lch){
fprintf(stderr,"%s: WAVE files must all have same number of channels.\n",fname);
exit(1);
}
if(rate!=lrate){
fprintf(stderr,"%s: WAVE files must all be same sampling rate.\n",fname);
exit(1);
}
if(inbytes!=lbits/8){
fprintf(stderr,"%s: WAVE files must all be same sample width.\n",fname);
exit(1);
}
}
fmtp=1;
} else if(!strncmp(buffer,"data",4)){
off_t pos=ftello(f);
if(!fmtp){
fprintf(stderr,"%s: WAVE fmt chunk must preceed data chunk.\n",fname);
exit(1);
}
datap=1;
if(seekable)
filelength=(filelength-pos)/(ch*inbytes)*(ch*inbytes)+pos;
if(chunklen==0UL ||
chunklen==0x7fffffffUL ||
chunklen==0xffffffffUL){
file_list[i-1].begin=total;
total=file_list[i-1].end=0;
fprintf(stderr,"%s: Incomplete header; assuming stream.\n",fname);
}else if(filelength==-1 || chunklen+pos<=filelength){
file_list[i-1].begin=total;
total=file_list[i-1].end=total+chunklen;
fprintf(stderr,"%s: Using declared file size.\n",fname);
}else{
file_list[i-1].begin=total;
total=file_list[i-1].end=total+filelength-pos;
fprintf(stderr,"%s: Using actual file size.\n",fname);
}
file_list[i-1].data=ftello(f);
break;
} else {
fprintf(stderr,"%s: Unknown chunk type %c%c%c%c; skipping.\n",fname,
buffer[0],buffer[1],buffer[2],buffer[3]);
for(j=0;j<(int)chunklen;j++)
if(fgetc(f)==EOF)break;
}
}
if(!datap){
fprintf(stderr,"%s: WAVE file has no data chunk.\n",fname);
exit(1);
}
}else{
fprintf(stderr,"%s: Unable to open file.\n",fname);
exit(1);
}
}
/* look at stdout... do we have a file or device? */
if(!isatty(STDOUT_FILENO)){
/* apparently; assume this is the file/device for output */
loop_flag=0;
outfileno=dup(STDOUT_FILENO);
dup2(STDERR_FILENO,STDOUT_FILENO);
}
<p> /* load config */
#if 0
{
configfd=open(".postfishrc",O_RDWR|O_CREAT,0666);
if(configfd>=0)load_settings(configfd);
}
#endif
/* set up the hack for interthread gtk event triggering through
input subversion */
if(pipe(eventpipe)){
fprintf(stderr,"Unable to open event pipe:\n"
" %s\n",strerror(errno));
exit(1);
}
aseek(0);
mainpanel_go(argc,argv);
playback_exit=1;
while(1){
if(playback_active){
sched_yield();
}else
break;
}
//save_settings(configfd);
if(configfd>=0)close(configfd);
return(0);
}
<p><p><p><p><p><p><p>1.1 postfish/mainpanel.h
Index: mainpanel.h
===================================================================
extern void mainpanel_go(int argc,char *argv[]);
<p><p>1.1 postfish/readout.h
Index: readout.h
===================================================================
#ifndef __READOUT_H__
#define __READOUT_H__
#include <sys/time.h>
#include <time.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtkcontainer.h>
#include <gtk/gtkframe.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtklabel.h>
G_BEGIN_DECLS
#define READOUT_TYPE (readout_get_type ())
#define READOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), READOUT_TYPE, Readout))
#define READOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), READOUT_TYPE, ReadoutClass))
#define IS_READOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), READOUT_TYPE))
#define IS_READOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), READOUT_TYPE))
typedef struct _Readout Readout;
typedef struct _ReadoutClass ReadoutClass;
truct _Readout{
GtkFrame frame;
GtkWidget *label;
GtkWidget *sizelabel;
};
truct _ReadoutClass{
GtkFrameClass parent_class;
void (* readout) (Readout *m);
};
GType readout_get_type (void);
GtkWidget* readout_new (char *markup);
void readout_set (Readout *m,char *markup);
G_END_DECLS
#endif
<p><p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list