[xiph-cvs] cvs commit: postfish form.c form.h postfish.c
Monty
xiphmont at xiph.org
Sat Nov 30 22:30:18 PST 2002
xiphmont 02/12/01 01:30:17
Modified: . form.c form.h postfish.c
Log:
Lots of minor added features; taking streams/files on stdin, allowing output
to file/dev on stdout
Monty
Revision Changes Path
1.3 +85 -74 postfish/form.c
Index: form.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/form.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- form.c 30 Nov 2002 07:30:29 -0000 1.2
+++ form.c 1 Dec 2002 06:30:17 -0000 1.3
@@ -30,6 +30,7 @@
#include <ncurses.h>
#include <pthread.h>
#include <math.h>
+#include <form.h>
static int cursor_active=0;
static int cursor_x;
@@ -37,6 +38,13 @@
extern pthread_mutex_t master_mutex;
+long pow10(int power){
+ long ret=1,i;
+ for(i=0;i<power;i++)
+ ret*=10;
+ return(ret);
+}
+
void *m_realloc(void *in,int bytes){
if(!in)
return(malloc(bytes));
@@ -78,40 +86,9 @@
}
ret=getch();
- if(ret>0)return(ret);
+ if(ret>=0)return(ret);
}
}
-/***************** simple form entry fields *******************/
-
-enum field_type { FORM_TIME, FORM_DB, FORM_P2 };
-
-typedef struct {
- enum field_type type;
- int x;
- int y;
- int width;
- int editwidth;
- int editgroup;
-
- int min;
- int max;
- int dpoint;
-
- void *var;
- int *flag;
- struct form *form;
-
- int cursor;
-} formfield;
-
-typedef struct form {
- formfield *fields;
- int count;
- int storage;
-
- int cursor;
- int editable;
-} form;
void form_init(form *f,int maxstorage,int editable){
memset(f,0,sizeof(*f));
@@ -133,7 +110,7 @@
getyx(stdscr,y,x);
move(f->y,f->x);
- if(f->form->editable){
+ if(f->form->editable && f->active){
if(focus){
attron(A_REVERSE);
}else{
@@ -148,11 +125,13 @@
switch(f->type){
case FORM_TIME:
{
- long mult=rint(pow(10,f->editwidth-1));
+ long mult=pow10(f->editwidth-1);
int zeroflag=0;
+ int count=0;
/*xxxHHHHH:MM:SS.HH*/
/* 9876543210*/
for(i=f->width-1;i>=0;i--){
+
switch(i){
case 2:
addch('.');
@@ -161,16 +140,26 @@
addch(':');
break;
default:
- if(lval!=-1 && ((lval/mult)%10 || i<5)){
- zeroflag=1;
- addch(48+(lval/mult)%10);
+ if(f->form->editable && focus && count==f->cursor)
+ attroff(A_REVERSE);
+
+ if(f->active){
+ if(lval!=-1 && ((lval/mult)%10 || i<5)){
+ zeroflag=1;
+ addch(48+(lval/mult)%10);
+ }else{
+ if(zeroflag)
+ addch('0');
+ else
+ addch(' ');
+ }
+ mult/=10;
+ if(f->form->editable && focus && count==f->cursor)
+ attron(A_REVERSE);
}else{
- if(zeroflag)
- addch('0');
- else
- addch(' ');
+ addch('-');
}
- mult/=10;
+ count++;
}
}
@@ -199,19 +188,26 @@
case FORM_P2:
{
char buf[80];
- snprintf(buf,80,"%*ld",f->width,lval);
- addstr(buf);
+ int i;
+ if(f->active){
+ snprintf(buf,80,"%*ld",f->width,lval);
+ addstr(buf);
+ }else
+ for(i=0;i<f->width;i++)addch('-');
if(focus)cursor_active=0;
}
break;
default:
{
char buf[80];
- if(f->dpoint)
- snprintf(buf,80,"%+*.1f",f->width,lval*.1);
- else
- snprintf(buf,80,"%+*ld",f->width,lval);
- addstr(buf);
+ if(f->active){
+ if(f->dpoint)
+ snprintf(buf,80,"%+*.1f",f->width,lval*.1);
+ else
+ snprintf(buf,80,"%+*ld",f->width,lval);
+ addstr(buf);
+ }else
+ for(i=0;i<f->width;i++)addch('-');
if(focus)cursor_active=0;
}
break;
@@ -227,8 +223,13 @@
draw_field(f->fields+i);
}
+void field_active(formfield *f,int activep){
+ f->active=activep;
+ draw_field(f);
+}
+
formfield *field_add(form *f,enum field_type type,int x,int y,int width,
- int group,void *var,int *flag,int d,int min, int max){
+ void *var,void (*cb)(void),int d,int min, int max){
int n=f->count;
if(f->storage==n)return(NULL);
if(width<1)return(NULL);
@@ -238,9 +239,9 @@
f->fields[n].y=y;
f->fields[n].width=width;
f->fields[n].var=var;
- f->fields[n].flag=flag;
+ f->fields[n].cb=cb;
f->fields[n].dpoint=d;
- f->fields[n].editgroup=group;
+ f->fields[n].active=1;
f->fields[n].min=min;
f->fields[n].max=max;
@@ -275,17 +276,25 @@
}
void form_next_field(form *f){
- int temp=f->cursor++;
- draw_field(f->fields+temp);
- if(f->cursor>=f->count)f->cursor=0;
- draw_field(f->fields+f->cursor);
+ int v=f->cursor;
+ int t=(v+1>=f->count?v+1:0);
+ while(t!=v && !f->fields[t].active)
+ t=(t+1>=f->count?t+1:0);
+
+ f->cursor=t;
+ draw_field(f->fields+v);
+ draw_field(f->fields+t);
}
void form_prev_field(form *f){
- int temp=f->cursor--;
- draw_field(f->fields+temp);
- if(f->cursor<0)f->cursor=f->count-1;
- draw_field(f->fields+f->cursor);
+ int v=f->cursor;
+ int t=(v-1<0?f->count-1:v-1);
+ while(t!=v && !f->fields[t].active)
+ t=(t-1<0?f->count-1:t-1);
+
+ f->cursor=t;
+ draw_field(f->fields+v);
+ draw_field(f->fields+t);
}
void form_left_field(form *f){
@@ -298,7 +307,7 @@
for(i=0;i<f->count;i++){
int tx=f->fields[i].x+f->fields[i].width-1;
int ty=f->fields[i].y;
- if(tx<x){
+ if(tx<x && f->fields[i].active){
double testdist=abs(ty-y)*100+abs(tx-x);
if(testdist<dist){
best=i;
@@ -322,7 +331,7 @@
for(i=0;i<f->count;i++){
int tx=f->fields[i].x;
int ty=f->fields[i].y;
- if(tx>x){
+ if(tx>x && f->fields[i].active){
double testdist=abs(ty-y)*100+abs(tx-x);
if(testdist<dist){
best=i;
@@ -346,7 +355,7 @@
for(i=0;i<f->count;i++){
int tx=f->fields[i].x;
int ty=f->fields[i].y;
- if(ty>y){
+ if(ty>y && f->fields[i].active){
double testdist=abs(ty-y)+abs(tx-x)*100;
if(testdist<dist){
best=i;
@@ -370,7 +379,7 @@
for(i=0;i<f->count;i++){
int tx=f->fields[i].x;
int ty=f->fields[i].y;
- if(ty<y){
+ if(ty<y && f->fields[i].active){
double testdist=abs(ty-y)+abs(tx-x)*100;
if(testdist<dist){
best=i;
@@ -427,23 +436,23 @@
switch(c){
case '=':
(*val)++;
- if(ff->flag)*(ff->flag)=1;
if(*val>ff->max)*val=ff->max;
+ if(ff->cb)ff->cb();
break;
case '+':
(*val)+=10;
- if(ff->flag)*(ff->flag)=1;
if(*val>ff->max)*val=ff->max;
+ if(ff->cb)ff->cb();
break;
case '-':
(*val)--;
- if(ff->flag)*(ff->flag)=1;
if(*val<ff->min)*val=ff->min;
+ if(ff->cb)ff->cb();
break;
case '_':
(*val)-=10;
- if(ff->flag)*(ff->flag)=1;
if(*val<ff->min)*val=ff->min;
+ if(ff->cb)ff->cb();
break;
default:
ret=c;
@@ -457,13 +466,13 @@
switch(c){
case '=':case '+':
(*val)*=2;
- if(ff->flag)*(ff->flag)=1;
if(*val>ff->max)*val=ff->max;
+ if(ff->cb)ff->cb();
break;
case '-':case '_':
(*val)/=2;
- if(ff->flag)*(ff->flag)=1;
if(*val<ff->min)*val=ff->min;
+ if(ff->cb)ff->cb();
break;
default:
ret=c;
@@ -478,26 +487,28 @@
case '0':case '1':case '2':case '3':case '4':
case '5':case '6':case '7':case '8':case '9':
{
- long mult=(int)rint(pow(10.,ff->editwidth-ff->cursor-1));
+ long mult=pow10(ff->editwidth-ff->cursor-1);
long oldnum=(*val/mult)%10;
- if(ff->flag)*(ff->flag)=1;
*val-=oldnum*mult;
+
+ if(*val==-1)*val=0;
*val+=(c-48)*mult;
ff->cursor++;
if(ff->cursor>=ff->editwidth)ff->cursor=ff->editwidth-1;
+ if(ff->cb)ff->cb();
}
break;
case KEY_BACKSPACE:case '\b':
{
- long mult=(int)rint(pow(10.,ff->editwidth-ff->cursor-1));
+ long mult=pow10(ff->editwidth-ff->cursor-1);
long oldnum=(*val/mult)%10;
- if(ff->flag)*(ff->flag)=1;
*val-=oldnum*mult;
ff->cursor--;
if(ff->cursor<0)ff->cursor=0;
+ if(ff->cb)ff->cb();
}
break;
default:
<p><p>1.2 +4 -3 postfish/form.h
Index: form.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/form.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- form.h 30 Nov 2002 06:41:24 -0000 1.1
+++ form.h 1 Dec 2002 06:30:17 -0000 1.2
@@ -29,17 +29,17 @@
int y;
int width;
int editwidth;
- int editgroup;
int min;
int max;
int dpoint;
void *var;
- int *flag;
+ void (*cb)(void);
struct form *form;
int cursor;
+ int active;
} formfield;
typedef struct form {
@@ -56,6 +56,7 @@
extern void draw_field(formfield *f);
extern void form_redraw(form *f);
extern formfield *field_add(form *f,enum field_type type,int x,int y,
- int width,int group,void *var,int *flag,
+ int width,void *var,void (*)(void),
int d,int min, int max);
extern int form_handle_char(form *f,int c);
+extern void field_active(formfield *f,int activep);
<p><p>1.3 +278 -150 postfish/postfish.c
Index: postfish.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- postfish.c 30 Nov 2002 07:30:29 -0000 1.2
+++ postfish.c 1 Dec 2002 06:30:17 -0000 1.3
@@ -64,6 +64,7 @@
#define MAX_BLOCKSIZE 32768
#define BANDS 35
+static int outfileno=-1;
static int inbytes=0;
static int outbytes=2;
static int rate=0;
@@ -93,7 +94,6 @@
long noiset[BANDS];
long used;
- char name[20];
} configprofile;
@@ -101,7 +101,7 @@
static long configactive=0;
static configprofile configlist[CONFIG_MAX]={
{
- 8192,1,300,-60,0,1,0,1,1,
+ 8192,2,300,-30,0,1,0,1,1,
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
1,
@@ -109,11 +109,11 @@
-120,-120,-120,-120,-120,-120,-120,-120,-120,
-120,-120,-120,-120,-120,-120,-120,-120,-120,
-120,-120,-120,-120,-120,-120,-120,-120},
- 1,"default"
+ 1,
}
};
static configprofile configdefault={
- 8192,1,300,-60,0,1,0,1,1,
+ 8192,2,300,-30,0,1,0,1,1,
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
1,
@@ -121,7 +121,7 @@
-120,-120,-120,-120,-120,-120,-120,-120,-120,
-120,-120,-120,-120,-120,-120,-120,-120,-120,
-120,-120,-120,-120,-120,-120,-120,-120},
- 0,"default"
+ 0,
};
static configprofile wc;
@@ -190,7 +190,6 @@
pthread_t tty_thread_id;
typedef struct {
- char *name;
FILE *f;
off_t begin;
@@ -203,6 +202,7 @@
int file_entries=0;
int current_file_entry_number=-1;
file_entry *current_file_entry=NULL;
+int seekable=0;
/* -------------------------------------- */
@@ -226,7 +226,7 @@
void update_N(){
- mvaddstr(N_Y,N_X+4," [n] Noise Filter ");
+ mvaddstr(N_Y,N_X+4," [n] Noise Gate ");
if(wc.noise_p){
attron(A_BOLD);
addstr("ON ");
@@ -239,6 +239,13 @@
}
+void dirty_the_noise(){
+ noise_dirty=1;
+}
+void dirty_the_eq(){
+ eq_dirty=1;
+}
+
void update_static_N(){
int i;
mvaddstr(N_Y+2, N_X," 63 ");
@@ -279,7 +286,8 @@
mvaddstr(N_Y+2+BANDS,N_X+27," +30");
for(i=0;i<BANDS;i++)
- field_add(&editf,FORM_DB,N_X+5,N_Y+2+i,4,0,&wc.noiset[i],&noise_dirty,0,-150,0);
+ field_add(&editf,FORM_DB,N_X+5,N_Y+2+i,4,&wc.noiset[i],
+ dirty_the_noise,0,-150,0);
}
void update_E(){
@@ -335,9 +343,54 @@
mvaddstr(E_Y+1,E_X+27," +0");
for(i=0;i<BANDS;i++)
- field_add(&editf,FORM_DB,E_X+5,E_Y+2+i,3,1,&wc.eqt[i],&eq_dirty,0,-30,30);
+ field_add(&editf,FORM_DB,E_X+5,E_Y+2+i,3,&wc.eqt[i],
+ dirty_the_eq,0,-30,30);
+}
+
+
+static formfield *A_field;
+static formfield *B_field;
+static formfield *T_field;
+
+static formfield *pre_field;
+static formfield *post_field;
+static formfield *limit_field;
+static long pre_var=0;
+static long post_var=0;
+
+off_t time_to_cursor(long t){
+ if(t<0)
+ return(-1);
+
+ {
+ off_t c=t%10000;
+
+ c+=t/10000%100*6000;
+ c+=t/1000000*600000;
+
+ return((off_t)rint(c*.01*rate)*ch*inbytes);
+ }
+}
+
+void dirty_A(){
+ Acursor=time_to_cursor(A);
+}
+void dirty_B(){
+ Bcursor=time_to_cursor(B);
+}
+
+long cursor_to_time(off_t c){
+ long T;
+ if(c<0)return(-1);
+ c=c*100./rate/ch/inbytes;
+ T =c/(100*60*60)*1000000;
+ T+=c/(100*60)%60*10000;
+ T+=c/(100)%60*100;
+ T+=c%100;
+ return(T);
}
+
void update_D(){
attron(A_BOLD);
@@ -353,30 +406,32 @@
else
addstr("OFF");
- move(D_Y+8,D_X+18);
- if(wc.dyn_p)
- addstr("ON ");
- else
- addstr("OFF");
-
+ move(D_Y+8,D_X+12);
+ switch(wc.dyn_p){
+ case 0:
+ addstr(" OFF");
+ field_active(limit_field,1);
+ break;
+ case 1:
+ addstr("BLOCK ATT");
+ field_active(limit_field,1);
+ break;
+ case 2:
+ addstr("SOFT CLIP");
+ field_active(limit_field,0);
+ break;
+ }
attrset(0);
}
-static formfield *A_field;
-static formfield *B_field;
-static formfield *T_field;
-
-static formfield *pre_field;
-static formfield *post_field;
-static long pre_var=0;
-static long post_var=0;
-
void update_static_D(){
mvaddstr(D_Y+0,D_X,"[m] Master Att dB");
- mvaddstr(D_Y+1,D_X,"[r] Dynamic Range db");
+ mvaddstr(D_Y+1,D_X,"[r] Dynamic Range dB");
mvaddstr(D_Y+2,D_X," Frame size");
+ mvaddstr(D_Y+5,D_X," dB");
+
mvvline(D_Y+5,D_X,0,1);
mvvline(D_Y+5,D_X+11,0,1);
mvvline(D_Y+5,D_X+22,0,1);
@@ -394,8 +449,9 @@
mvaddstr(D_Y+6,D_X+10," 0 ");
mvaddstr(D_Y+6,D_X+18," +30");
- mvaddstr(D_Y+8,D_X,"[l] Dynamic Limit dB");
- mvaddstr(D_Y+9,D_X," peak integral ms");
+ mvaddstr(D_Y+8,D_X,"[l] Limiter dB");
+ mvaddstr(D_Y+9,D_X," Block period ms");
+ mvaddstr(D_Y+11,D_X," dB");
mvvline(D_Y+11,D_X,0,1);
mvvline(D_Y+11,D_X+11,0,1);
@@ -414,23 +470,27 @@
mvaddstr(D_Y+12,D_X+10," A ");
mvaddstr(D_Y+12,D_X+19," +0");
- field_add(&editf,FORM_DB,D_X+23,D_Y+0,5,2,&wc.masteratt,NULL,1,-900,+900);
- field_add(&editf,FORM_DB,D_X+23,D_Y+1,5,3,&wc.dynamicatt,NULL,1,-900,+900);
- field_add(&editf,FORM_P2,D_X+23,D_Y+2,5,4,&wc.block_a,NULL,0,64,MAX_BLOCKSIZE);
- field_add(&editf,FORM_DB,D_X+23,D_Y+8,5,5,&wc.dynt,NULL,1,-300,0);
- field_add(&editf,FORM_DB,D_X+23,D_Y+9,5,6,&wc.dynms,NULL,0,0,MAX_DECAY_MS);
+ field_add(&editf,FORM_DB,D_X+23,D_Y+0,5,&wc.masteratt,NULL,1,-900,+900);
+ field_add(&editf,FORM_DB,D_X+23,D_Y+1,5,&wc.dynamicatt,NULL,1,-900,+900);
+ field_add(&editf,FORM_P2,D_X+23,D_Y+2,5,&wc.block_a,NULL,0,64,MAX_BLOCKSIZE);
+ field_add(&editf,FORM_DB,D_X+23,D_Y+8,5,&wc.dynt,NULL,1,-300,0);
+ limit_field=field_add(&editf,FORM_DB,D_X+23,D_Y+9,5,&wc.dynms,NULL,0,0,MAX_DECAY_MS);
mvaddstr(D_Y+14,D_X,"[a] [A] Clear");
mvaddstr(D_Y+15,D_X,"[b] [B] Clear");
- A_field=field_add(&editf,FORM_TIME,D_X+4,D_Y+14,11,9,&A,NULL,0,0,99999999);
- B_field=field_add(&editf,FORM_TIME,D_X+4,D_Y+15,11,10,&B,NULL,0,0,99999999);
+ A_field=field_add(&editf,FORM_TIME,D_X+4,D_Y+14,11,&A,dirty_A,0,0,99999999);
+ B_field=field_add(&editf,FORM_TIME,D_X+4,D_Y+15,11,&B,dirty_B,0,0,99999999);
+ if(!seekable){
+ field_active(A_field,0);
+ field_active(B_field,0);
+ }
noneditf.cursor=-1;
- T_field=field_add(&noneditf,FORM_TIME,D_X+4,D_Y+16,11,0,&T,NULL,0,0,99999999);
+ T_field=field_add(&noneditf,FORM_TIME,D_X+4,D_Y+16,11,&T,NULL,0,0,99999999);
- pre_field=field_add(&noneditf,FORM_DB,D_X+23,D_Y+5,5,0,&pre_var,NULL,0,-30,30);
- post_field=field_add(&noneditf,FORM_DB,D_X+23,D_Y+11,5,0,&post_var,NULL,0,-30,0);
+ pre_field=field_add(&noneditf,FORM_DB,D_X+23,D_Y+5,5,&pre_var,NULL,0,-30,30);
+ post_field=field_add(&noneditf,FORM_DB,D_X+23,D_Y+11,5,&post_var,NULL,0,-30,0);
}
@@ -489,26 +549,26 @@
void update_static_0(){
mvaddstr(T_Y,T_X,"[0>");
- field_add(&noneditf,FORM_TIME,T_X+3,T_Y,11,0,&TX[0],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+3,T_Y,11,&TX[0],NULL,0,0,99999999);
mvaddstr(T_Y,T_X+19,"[1>");
- field_add(&noneditf,FORM_TIME,T_X+21,T_Y,11,0,&TX[1],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+21,T_Y,11,&TX[1],NULL,0,0,99999999);
mvaddstr(T_Y,T_X+38,"[2>");
- field_add(&noneditf,FORM_TIME,T_X+41,T_Y,11,0,&TX[2],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+41,T_Y,11,&TX[2],NULL,0,0,99999999);
mvaddstr(T_Y,T_X+57,"[3>");
- field_add(&noneditf,FORM_TIME,T_X+60,T_Y,11,0,&TX[3],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+60,T_Y,11,&TX[3],NULL,0,0,99999999);
mvaddstr(T_Y,T_X+76,"[4>");
- field_add(&noneditf,FORM_TIME,T_X+79,T_Y,11,0,&TX[4],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+79,T_Y,11,&TX[4],NULL,0,0,99999999);
mvaddstr(T_Y+1,T_X,"[5>");
- field_add(&noneditf,FORM_TIME,T_X+3,T_Y+1,11,0,&TX[5],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+3,T_Y+1,11,&TX[5],NULL,0,0,99999999);
mvaddstr(T_Y+1,T_X+19,"[6>");
- field_add(&noneditf,FORM_TIME,T_X+21,T_Y+1,11,0,&TX[6],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+21,T_Y+1,11,&TX[6],NULL,0,0,99999999);
mvaddstr(T_Y+1,T_X+38,"[7>");
- field_add(&noneditf,FORM_TIME,T_X+41,T_Y+1,11,0,&TX[7],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+41,T_Y+1,11,&TX[7],NULL,0,0,99999999);
mvaddstr(T_Y+1,T_X+57,"[8>");
- field_add(&noneditf,FORM_TIME,T_X+60,T_Y+1,11,0,&TX[8],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+60,T_Y+1,11,&TX[8],NULL,0,0,99999999);
mvaddstr(T_Y+1,T_X+76,"[9>");
- field_add(&noneditf,FORM_TIME,T_X+79,T_Y+1,11,0,&TX[9],NULL,0,0,99999999);
+ field_add(&noneditf,FORM_TIME,T_X+79,T_Y+1,11,&TX[9],NULL,0,0,99999999);
}
@@ -520,31 +580,6 @@
draw_field(B_field);
}
-off_t time_to_cursor(long t){
- if(t<0)
- return(-1);
-
- {
- off_t c=t%10000;
-
- c+=t/10000%100*6000;
- c+=t/1000000*600000;
-
- return((off_t)rint(c*.01*rate)*ch*inbytes);
- }
-}
-
-long cursor_to_time(off_t c){
- long T;
- if(c<0)return(-1);
- c=c*100./rate/ch/inbytes;
- T =c/(100*60*60)*1000000;
- T+=c/(100*60)%60*10000;
- T+=c/(100)%60*100;
- T+=c%100;
- return(T);
-}
-
void update_ui(){
int i,j;
@@ -778,23 +813,20 @@
pthread_mutex_unlock(&master_mutex);
}
-/* return a scaled amplitude */
-inline double atan_amplitude(double amplitude,double thresh){
+inline double inv_amplitude(double amplitude,double thresh){
if(fabs(amplitude)>thresh){
- /* use a scaled atan() rolloff, which will begin with a 1:1 slope
- but asymptotically approach our limit */
- double scale=(1./(M_PI*.5))*(1.-thresh);
+ double scale=(1.-thresh);
if(amplitude>0)
- return(atan((amplitude-thresh)/scale)*scale + thresh );
+ return ( (amplitude-thresh)/(scale+(amplitude-thresh)) )*scale + thresh ;
else
- return(atan((amplitude+thresh)/scale)*scale - thresh );
+ return ( (thresh+amplitude)/(scale-(thresh+amplitude)) )*scale - thresh ;
}else
return(amplitude);
}
-inline double atan_scale(double amplitude,double thresh){
+inline double inv_scale(double amplitude,double thresh){
if(amplitude==0.)return 1.;
- return(atan_amplitude(amplitude,thresh)/amplitude);
+ return(inv_amplitude(amplitude,thresh)/amplitude);
}
/* limit output by block; atan-scale according to max amplitude */
@@ -820,21 +852,37 @@
for(i=1;i<j;i++)
if(y<dyn_decay[i])y=dyn_decay[i];
- d=atan_scale(y,thresh);
+ d=inv_scale(y,thresh);
y=dyn_decay[0];
pthread_mutex_lock(&master_mutex);
+
+ /* valid for either block att or soft clip */
if(maxtimepre<y)maxtimepre=y;
if(maxtimepost<y*d)maxtimepost=y*d;
if(maxtimeprehold<y)maxtimeprehold=y;
if(maxtimeposthold<y*d)maxtimeposthold=y*d;
- if(wc.dyn_p && d!=1.){
- pthread_mutex_unlock(&master_mutex);
+ switch(wc.dyn_p){
+ case 2:
+ d=thresh;
+ pthread_mutex_unlock(&master_mutex);
+
for(j=0;j<ch;j++)
for(i=0;i<block;i++)
- b[j][i]*=d;
- }else{
+ b[j][i]=inv_amplitude(b[j][i],d);
+ break;
+ case 1:
+ if(d!=1.){
+ pthread_mutex_unlock(&master_mutex);
+
+ for(j=0;j<ch;j++)
+ for(i=0;i<block;i++)
+ b[j][i]*=d;
+ break;
+ }
+ /* partial fall-through */
+ default:
pthread_mutex_unlock(&master_mutex);
}
}
@@ -991,6 +1039,11 @@
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++){
@@ -1024,11 +1077,22 @@
double M,S;
pthread_mutex_lock(&master_mutex);
- if(Bcursor<0 && cursor>=current_file_entry->end){
+
+ /* 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);
@@ -1044,10 +1108,16 @@
ret=fread(readbuf+read_b,1,read_this_loop,current_file_entry->f);
- if(ret>=0){
+ 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){
@@ -1057,10 +1127,6 @@
current_file_entry_number++;
current_file_entry++;
fseeko(current_file_entry->f,current_file_entry->data,SEEK_SET);
- }else{
- memset(readbuf+read_b,0,toread_b);
- read_b+=toread_b;
- toread_b=0;
}
}
}
@@ -1109,8 +1175,11 @@
i++;
}
}
+
void WriteWav(FILE *f,long channels,long rate,long bits,long duration){
- fseek(f,0,SEEK_SET);
+ if(ftell(f)>0)
+ if(fseek(f,0,SEEK_SET))
+ return;
fprintf(f,"RIFF");
PutNumLE(duration+44-8,f,4);
fprintf(f,"WAVEfmt ");
@@ -1125,10 +1194,17 @@
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 *vfile){
+void *playback_thread(void *dummy){
FILE *playback_fd=NULL;
- char *file=(char *)vfile;
int i,j,k;
int format=AFMT_S16_NE;
int channels=ch;
@@ -1143,6 +1219,7 @@
int bigendianp=0;
double scale;
int last=0;
+ off_t count=0;
pthread_mutex_lock(&master_mutex);
block=wc.block_a;
@@ -1160,22 +1237,31 @@
dyn_decay=alloca(sizeof(*dyn_decay)*dyn_decaysize);
memset(dyn_decay,0,sizeof(*dyn_decay)*dyn_decaysize);
- if(!strcmp(file,"stdout")){
- playback_fd=stdout;
+ if(outfileno==-1){
+ playback_fd=fopen("/dev/dsp","wb");
}else{
- playback_fd=fopen(file,"wb");
- if(!playback_fd){
- pthread_mutex_lock(&master_mutex);
- playback_active=0;
- playback_exit=0;
- pthread_mutex_unlock(&master_mutex);
- return NULL;
- }
+ playback_fd=fdopen(dup(outfileno),"wb");
+ }
+ if(!playback_fd){
+ pthread_mutex_lock(&master_mutex);
+ playback_active=0;
+ playback_exit=0;
+ pthread_mutex_unlock(&master_mutex);
+ return NULL;
}
- if(!strncmp(file,"/dev/",5)){
-
+ /* is this file a block device? */
+ if(isachr(playback_fd)){
+ int fragment=0x7fff000d;
+
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");
@@ -1195,7 +1281,7 @@
if(AFMT_S16_NE==AFMT_S16_BE)bigendianp=1;
}else{
- WriteWav(playback_fd,ch,rate,outbytes*8,file_list[file_entries-1].end);
+ WriteWav(playback_fd,ch,rate,outbytes*8,-1);
}
buf=alloca(sizeof(*buf)*ch);
@@ -1314,10 +1400,12 @@
last=foo;
}
- fwrite(audiobuf,1,audiobufsize,playback_fd);
+ count+=fwrite(audiobuf,1,audiobufsize,playback_fd);
}
+ if(!isachr(playback_fd))WriteWav(playback_fd,ch,rate,outbytes*8,count);
+
pthread_mutex_lock(&master_mutex);
fclose(playback_fd);
playback_active=0;
@@ -1339,7 +1427,8 @@
if(!of)perror("failed to open data dump file");
for(j=0;j<n;j++){
- fprintf(of,"%f ",(double)toOC((j+1)*22050./n)*2);
+ //fprintf(of,"%f ",(double)toOC((j+1)*22050./n)*2);
+ fprintf(of,"%d ",j);
if(dB){
float val;
@@ -1391,7 +1480,6 @@
fprintf(f,"MASTERATT_P:%ld\n",configlist[i].masteratt_p);
fprintf(f,"DYNAMICATT_P:%ld\n",configlist[i].dynamicatt_p);
- fprintf(f,"NAME:%s\n",configlist[i].name);
}
}
@@ -1474,7 +1562,6 @@
confparse_ld(buffer,"MASTERATT_P",&configlist[i].masteratt_p);
confparse_ld(buffer,"DYNAMICATT_P",&configlist[i].dynamicatt_p);
- confparse_s(buffer,"NAME",configlist[i].name,sizeof(configlist[i].name));
}
confparse_ld(buffer,"A",&A);
@@ -1520,33 +1607,62 @@
off_t total=0;
int i,j;
int configfd;
+ int stdinp=0;
+ char *fname="stdin";
/* parse command line and open all the input files */
- file_list=calloc(argc-1,sizeof(file_entry));
- file_entries=argc-1;
- for(i=1;i<argc;i++){
- FILE *f=fopen(argv[i],"rb");
+ 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].name=strdup(argv[i]);
file_list[i-1].f=f;
/* parse header (well, sort of) and get file size */
- fseek(f,0,SEEK_END);
- filelength=ftello(f);
- fseek(f,0,SEEK_SET);
+ 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",argv[i]);
+ fprintf(stderr,"%s: Not a WAVE file.\n",fname);
exit(1);
}
while(fread(buffer,1,8,f)==8){
- int chunklen=buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
+ unsigned long chunklen=
+ buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
if(!strncmp(buffer,"fmt ",4)){
int ltype;
@@ -1555,7 +1671,7 @@
int lbits;
if(chunklen>80){
- fprintf(stderr,"%s: WAVE file fmt chunk too large to parse.\n",argv[i]);
+ fprintf(stderr,"%s: WAVE file fmt chunk too large to parse.\n",fname);
exit(1);
}
fread(buffer,1,chunklen,f);
@@ -1566,7 +1682,7 @@
lbits=buffer[14]|(buffer[15]<<8);
if(ltype!=1){
- fprintf(stderr,"%s: WAVE file not PCM.\n",argv[i]);
+ fprintf(stderr,"%s: WAVE file not PCM.\n",fname);
exit(1);
}
@@ -1577,15 +1693,15 @@
if(inbytes>1)signp=1;
}else{
if(ch!=lch){
- fprintf(stderr,"%s: WAVE files must all have same number of channels.\n",argv[i]);
+ 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",argv[i]);
+ 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",argv[i]);
+ fprintf(stderr,"%s: WAVE files must all be same sample width.\n",fname);
exit(1);
}
}
@@ -1593,55 +1709,65 @@
} else if(!strncmp(buffer,"data",4)){
off_t pos=ftello(f);
if(!fmtp){
- fprintf(stderr,"%s: WAVE fmt chunk must preceed data chunk.\n",argv[i]);
+ fprintf(stderr,"%s: WAVE fmt chunk must preceed data chunk.\n",fname);
exit(1);
}
datap=1;
- filelength=(filelength-pos)/(ch*inbytes)*(ch*inbytes)+pos;
-
- if(chunklen+pos<=filelength){
+ 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",argv[i]);
+ 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",argv[i]);
+ 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",argv[i],
+ 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<chunklen;j++)
+ for(j=0;j<(int)chunklen;j++)
if(fgetc(f)==EOF)break;
}
}
if(!datap){
- fprintf(stderr,"%s: WAVE file has no data chunk.\n",argv[i]);
+ fprintf(stderr,"%s: WAVE file has no data chunk.\n",fname);
exit(1);
}
}else{
- fprintf(stderr,"%s: Unable to open file.\n",argv[i]);
+ 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 */
+ outfileno=dup(STDOUT_FILENO);
+ dup2(STDERR_FILENO,STDOUT_FILENO);
+ }
+
+
/* load config */
{
configfd=open(".postfishrc",O_RDWR|O_CREAT,0666);
if(configfd>=0)load_settings(configfd);
}
- /* are we running in batch mode? */
- if(!strcmp(argv[0],"postfish-batch")){
- playback_thread("stdout");
- exit(0);
- }
-
/* set up the hack for interthread ncurses event triggering through
input subversion */
ttyfd=open("/dev/tty",O_RDONLY);
@@ -1688,9 +1814,9 @@
form_init(&editf,120,1);
form_init(&noneditf,50,0);
box(stdscr,0,0);
- mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.2 2002/11/30 07:30:29 xiphmont Exp $ ");
+ mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.3 2002/12/01 06:30:17 xiphmont Exp $ ");
mvaddstr(LINES-1, 2,
- " [<]<< [,]< [Spc] Play/Pause [Bksp] Stop [.]> [>]>> [p] Process ");
+ " [<]<< [,]< [Spc] Play/Pause [Bksp] Stop/Cue [.]> [>]>> ");
mvaddstr(LINES-1, COLS-12, " [q] Quit ");
@@ -1710,7 +1836,7 @@
update_static_0();
refresh();
-
+
signal(SIGINT,SIG_IGN);
while(1){
@@ -1755,7 +1881,8 @@
break;
case 'l':
pthread_mutex_lock(&master_mutex);
- wc.dyn_p=!wc.dyn_p;
+ wc.dyn_p++;
+ if(wc.dyn_p>2)wc.dyn_p=0;
pthread_mutex_unlock(&master_mutex);
update_D();
break;
@@ -1823,9 +1950,9 @@
}
update_a();
}else{
- Acursor=time_to_cursor(A);
aseek(Acursor);
pthread_mutex_unlock(&master_mutex);
+ update_play();
}
break;
case 'b':
@@ -1843,6 +1970,7 @@
update_b();
}else
pthread_mutex_unlock(&master_mutex);
+ update_play();
break;
case 'A':
pthread_mutex_lock(&master_mutex);
@@ -1873,7 +2001,7 @@
break;
}
}
- cursor=Acursor;
+ aseek(Acursor);
pthread_mutex_unlock(&master_mutex);
update_play();
break;
@@ -1883,7 +2011,7 @@
playback_active=1;
pthread_mutex_unlock(&master_mutex);
update_play();
- pthread_create(&playback_thread_id,NULL,&playback_thread,"/dev/dsp");
+ pthread_create(&playback_thread_id,NULL,&playback_thread,NULL);
}else{
playback_exit=1;
pthread_mutex_unlock(&master_mutex);
<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