Commit 3ee56d52 authored by Monty Montgomery's avatar Monty Montgomery

Commit in-progress work


git-svn-id: https://svn.xiph.org/trunk/postfish@5464 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 92cc1628
......@@ -300,7 +300,7 @@ int input_load(int n,char *list[]){
}
}
out.samples=4096;
out.samples=2048;
input_ch=out.channels=ch;
out.rate=rate;
out.data=malloc(sizeof(*out.data)*ch);
......@@ -345,10 +345,53 @@ int input_seek(off_t pos){
return(0);
}
double *input_rms=NULL;
double *input_peak=NULL;
sig_atomic_t input_feedback=0;
static void update_input_feedback(double *peak,double *rms){
int i,n=input_ch+2;
pthread_mutex_lock(&master_mutex);
if(!input_rms){
input_rms=calloc(n,sizeof(*input_rms));
input_peak=calloc(n,sizeof(*input_peak));
}
if(input_feedback==0)
for(i=0;i<n;i++)input_peak[i]*=.9;
for(i=0;i<n;i++)input_rms[i]=.8*input_rms[i]+.2*rms[i];
for(i=0;i<n;i++)
if(peak[i]>input_peak[i])
input_peak[i]=peak[i];
input_feedback=1;
pthread_mutex_unlock(&master_mutex);
}
int fetch_input_feedback(double *peak,double *rms){
int n=input_ch+2,i,j;
pthread_mutex_lock(&master_mutex);
memcpy(rms,input_rms,sizeof(*input_rms)*n);
memcpy(peak,input_peak,sizeof(*input_peak)*n);
input_feedback=0;
pthread_mutex_unlock(&master_mutex);
}
time_linkage *input_read(void){
int read_b=0,i,j,k;
int toread_b=out.samples*out.channels*inbytes;
unsigned char *readbuf;
double *rms=alloca(sizeof(*rms)*(out.channels+2));
double *peak=alloca(sizeof(*peak)*(out.channels+2));
memset(rms,0,sizeof(*rms)*(out.channels+2));
memset(peak,0,sizeof(*peak)*(out.channels+2));
pthread_mutex_lock(&master_mutex);
......@@ -394,19 +437,27 @@ time_linkage *input_read(void){
if(loop_active && cursor>=Bcursor){
pthread_mutex_unlock(&master_mutex);
input_seek(Acursor);
}else if(cursor>=current_file_entry->end){
pthread_mutex_unlock(&master_mutex);
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);
}
}else{
if(cursor>=current_file_entry->end){
pthread_mutex_unlock(&master_mutex);
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);
}
}else
pthread_mutex_unlock(&master_mutex);
}
}
k=0;
for(i=0;i<out.samples;i++){
double mean=0.;
double div=0.;
double divrms=0.;
for(j=0;j<out.channels;j++){
double dval;
long val=0;
switch(inbytes){
case 1:
......@@ -423,12 +474,41 @@ time_linkage *input_read(void){
break;
}
if(signp)
out.data[j][i]=val*4.6566128730e-10;
dval=out.data[j][i]=val*4.6566128730e-10;
else
out.data[j][i]=(val^0x80000000UL)*4.6566128730e-10;
dval=out.data[j][i]=(val^0x80000000UL)*4.6566128730e-10;
if(fabs(dval)>peak[j])peak[j]=fabs(dval);
rms[j]+= dval*dval;
mean+=dval;
k+=inbytes;
}
/* mean */
mean/=j;
if(fabs(mean)>peak[j])peak[j]=fabs(mean);
rms[j]+= mean*mean;
/* div */
for(j=0;j<out.channels;j++){
double dval=mean-out.data[j][i];
if(fabs(dval)>peak[out.channels+1])peak[out.channels+1]=fabs(dval);
divrms+=dval*dval;
}
rms[out.channels+1]+=divrms/out.channels;
}
for(j=0;j<out.channels+2;j++){
rms[j]/=out.samples;
rms[j]=sqrt(rms[j]);
}
update_input_feedback(peak,rms);
return &out;
}
......@@ -47,6 +47,11 @@ typedef struct {
GtkWidget *deckactive[7];
GtkWidget *inbar;
GtkWidget *outbar;
GtkWidget *channelshow[10]; /* support only up to 8 + mid/side */
/* ui state */
int fishframe;
int fishframe_init;
......@@ -58,7 +63,7 @@ extern sig_atomic_t playback_active;
extern sig_atomic_t playback_exit;
extern void *playback_thread(void *dummy);
static void action_play(GtkWidget *dummy,postfish_mainpanel *p){
static void action_play(GtkWidget *widget,postfish_mainpanel *p){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
if(!playback_active){
pthread_t playback_thread_id;
......@@ -487,10 +492,10 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
/* right side of main panel */
{
char *labels[12]={"-96","-72","-48","-24","-20","-16",
"-12","-8","-4","0","+3","+6"};
float levels[13]={-140,-96,-72,-48,-24,-20,-16,
-12,-8,-4,0,+3,+6};
char *labels[12]={"-96","-72","-60","-48","-36","-24",
"-16","-8","-3","0","+3","+6"};
double levels[13]={-140.,-96.,-72.,-60.,-48.,-36.,-24.,
-16.,-8.,-3.,0.,+3.,+6.};
GtkWidget *ttable=gtk_table_new(7,2,0);
GtkWidget *togglebox=gtk_hbox_new(0,0);
......@@ -499,8 +504,9 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
GtkWidget *show=gtk_label_new("show:");
GtkWidget *inframe=gtk_frame_new(NULL);
GtkWidget *outframe=gtk_frame_new(NULL);
GtkWidget *inbar=multibar_new(12,labels,levels);
GtkWidget *outbar=multibar_new(12,labels,levels);
panel->inbar=multibar_new(12,labels,levels);
panel->outbar=multibar_new(12,labels,levels);
gtk_container_set_border_width(GTK_CONTAINER (ttable), 3);
gtk_table_set_col_spacings(GTK_TABLE(ttable),5);
......@@ -513,19 +519,20 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
if(!chlabels[i])break;
GtkWidget *button=gtk_check_button_new_with_mnemonic(chlabels[i]);
if(i<2)gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
if(i<input_ch)gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
gtk_box_pack_start(GTK_BOX(togglebox),button,0,0,0);
{
char buffer[]="color\0\0";
buffer[5]= (i%10)+48;
gtk_widget_set_name(button,buffer);
}
panel->channelshow[i]=button;
}
gtk_frame_set_shadow_type(GTK_FRAME(inframe),GTK_SHADOW_ETCHED_IN);
gtk_frame_set_shadow_type(GTK_FRAME(outframe),GTK_SHADOW_ETCHED_IN);
gtk_container_add(GTK_CONTAINER(inframe),inbar);
gtk_container_add(GTK_CONTAINER(outframe),outbar);
gtk_container_add(GTK_CONTAINER(inframe),panel->inbar);
gtk_container_add(GTK_CONTAINER(outframe),panel->outbar);
gtk_table_attach_defaults(GTK_TABLE(ttable),togglebox,1,3,0,1);
gtk_table_attach(GTK_TABLE(ttable),show,0,1,0,1,GTK_FILL|GTK_SHRINK,GTK_FILL|GTK_SHRINK,0,0);
......@@ -688,6 +695,43 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
}
static void async_event_handle(gpointer data,
int fd,
GdkInputCondition condition){
postfish_mainpanel *panel=data;
int i;
char buf[1];
read(eventpipe[0],buf,1);
/* first order of business: release the play button if playback is
no longer in progress */
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->buttonactive[3])))
if(!playback_active)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->buttonactive[3]),0);
/* second order of business; update the input meter if data is available */
if(input_feedback){
double *rms=alloca(sizeof(*rms)*(input_ch+2));
double *peak=alloca(sizeof(*peak)*(input_ch+2));
fetch_input_feedback(peak,rms);
for(i=0;i<input_ch+2;i++){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->channelshow[i]))){
peak[i]=todB(peak[i]);
rms[i]=todB(rms[i]);
}else{
peak[i]=-400;
rms[i]=-400;
}
}
multibar_set(MULTIBAR(panel->inbar),rms,peak,input_ch+2);
}
}
#include <stdlib.h>
void mainpanel_go(int argc,char *argv[], int ch){
postfish_mainpanel p;
......@@ -728,10 +772,11 @@ void mainpanel_go(int argc,char *argv[], int ch){
sprintf(buffer,"_%d",i);
labels[i]=strdup(buffer);
}
sprintf(buffer,"_%d mean",i);
sprintf(buffer,"_%d mid",i);
labels[i++]=strdup(buffer);
sprintf(buffer,"_%d diff",i);
sprintf(buffer,"_%d div",i);
labels[i++]=strdup(buffer);
break;
default:
fprintf(stderr,"\nPostfish currently supports inputs of one to eight\n"
"channels (current input request: %d channels)\n\n",ch);
......@@ -740,11 +785,11 @@ void mainpanel_go(int argc,char *argv[], int ch){
mainpanel_create(&p,labels);
animate_fish(&p);
gtk_input_add_full(eventpipe[0],GDK_INPUT_READ,async_event_handle,NULL,
&p,NULL);
gtk_main ();
}
......@@ -2,10 +2,10 @@
#include <stdlib.h>
#include "multibar.h"
static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
static void draw(GtkWidget *widget,double *lowvals, double *highvals, int n){
int i,j;
Multibar *m=MULTIBAR(widget);
float max=m->peak;
double max=m->peak;
if(!m->boxcolor){
m->boxcolor=gdk_gc_new(m->backing);
......@@ -13,7 +13,7 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
}
if(m->cliptimer.tv_sec){
struct timeval tv;
struct timeval tv;
gettimeofday(&tv,NULL);
long val=(tv.tv_sec-m->cliptimer.tv_sec)*1000+(tv.tv_usec-m->cliptimer.tv_usec)/1000;
......@@ -26,7 +26,7 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
long val=(tv.tv_sec-m->peaktimer.tv_sec)*1000+(tv.tv_usec-m->peaktimer.tv_usec)/1000;
if(val>1000) m->peak -= (val-1000)*.1;
if(val>1500) max = m->peak -= (val-1500)*.01;
}
for(i=0;i<n;i++)
......@@ -52,7 +52,7 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
for(j=0;j<=m->labels;j++)
if(lowvals[i]>=m->levels[j]){
if(lowvals[i]<=m->levels[j+1]){
float del=(lowvals[i]-m->levels[j])/(m->levels[j+1]-m->levels[j]);
double del=(lowvals[i]-m->levels[j])/(m->levels[j+1]-m->levels[j]);
pixlo[i]=(j+del)/m->labels*widget->allocation.width;
break;
}
......@@ -63,7 +63,7 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
for(;j<=m->labels;j++)
if(highvals[i]>=m->levels[j]){
if(highvals[i]<=m->levels[j+1]){
float del=(highvals[i]-m->levels[j])/(m->levels[j+1]-m->levels[j]);
double del=(highvals[i]-m->levels[j])/(m->levels[j+1]-m->levels[j]);
pixhi[i]=(j+del)/m->labels*widget->allocation.width;
break;
}
......@@ -142,27 +142,14 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
}
}
for(i=0;i<m->labels;i++){
int x=widget->allocation.width*(i+1)/m->labels;
int y=widget->allocation.height;
int px,py;
gdk_draw_line (m->backing,
widget->style->text_gc[0],
x, 0, x, y);
pango_layout_get_pixel_size(m->layout[i],&px,&py);
x-=px+2;
y-=py;
y/=2;
gdk_draw_line (m->backing,
widget->style->white_gc,
0, 0, widget->allocation.width-1, 0);
gdk_draw_layout (m->backing,
widget->style->text_gc[0],
x, y,
m->layout[i]);
}
gdk_draw_line (m->backing,
widget->style->white_gc,
0, widget->allocation.height-1,
widget->allocation.width-1, widget->allocation.height-1);
/* peak follower */
{
......@@ -170,7 +157,7 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
for(j=0;j<=m->labels;j++)
if(m->peak>=m->levels[j]){
if(m->peak<=m->levels[j+1]){
float del=(m->peak-m->levels[j])/(m->levels[j+1]-m->levels[j]);
double del=(m->peak-m->levels[j])/(m->levels[j+1]-m->levels[j]);
x=(j+del)/m->labels*widget->allocation.width;
break;
}
......@@ -178,15 +165,37 @@ static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
break;
gdk_draw_polygon(m->backing,widget->style->black_gc,1,
gdk_draw_polygon(m->backing,widget->style->fg_gc[0],1,
(GdkPoint[]){{x,5},{x+5,0},{x-4,0}},3);
gdk_draw_polygon(m->backing,widget->style->black_gc,1,
gdk_draw_polygon(m->backing,widget->style->fg_gc[0],1,
(GdkPoint[]){{x,widget->allocation.height-6},
{x+5,widget->allocation.height},
{x-5,widget->allocation.height}},3);
gdk_draw_line(m->backing,widget->style->black_gc,x,0,x,widget->allocation.height-1);
gdk_draw_line(m->backing,widget->style->fg_gc[1],x,0,x,widget->allocation.height-1);
}
for(i=0;i<m->labels;i++){
int x=widget->allocation.width*(i+1)/m->labels;
int y=widget->allocation.height;
int px,py;
gdk_draw_line (m->backing,
widget->style->text_gc[0],
x, 0, x, y);
pango_layout_get_pixel_size(m->layout[i],&px,&py);
x-=px+2;
y-=py;
y/=2;
gdk_draw_layout (m->backing,
widget->style->text_gc[0],
x, y,
m->layout[i]);
}
......@@ -280,7 +289,7 @@ GType multibar_get_type (void){
return m_type;
}
GtkWidget* multibar_new (int n, char **labels, float *levels){
GtkWidget* multibar_new (int n, char **labels, double *levels){
int i;
GtkWidget *ret= GTK_WIDGET (g_object_new (multibar_get_type (), NULL));
Multibar *m=MULTIBAR(ret);
......@@ -297,7 +306,7 @@ GtkWidget* multibar_new (int n, char **labels, float *levels){
return ret;
}
void multibar_set(Multibar *m,float *lo, float *hi, int n){
void multibar_set(Multibar *m,double *lo, double *hi, int n){
GtkWidget *widget=GTK_WIDGET(m);
draw(widget,lo,hi,n);
gdk_draw_pixmap(widget->window,
......
......@@ -27,10 +27,10 @@ struct _Multibar{
int labels;
PangoLayout **layout;
float *levels;
double *levels;
GdkGC *boxcolor;
float peak;
double peak;
struct timeval cliptimer;
struct timeval peaktimer;
......@@ -44,9 +44,9 @@ struct _MultibarClass{
};
GType multibar_get_type (void);
GtkWidget* multibar_new (int n, char **labels, float *levels);
GtkWidget* multibar_new (int n, char **labels, double *levels);
void multibar_clear (Multibar *m);
void multibar_set (Multibar *m,float *lo,float *hi, int n);
void multibar_set (Multibar *m,double *lo,double *hi, int n);
G_END_DECLS
......
......@@ -82,7 +82,7 @@ static FILE *playback_startup(int outfileno, int ch, int r){
/* is this file a block device? */
if(isachr(playback_fd)){
int fragment=0x7fff000d;
int fragment=0x0004000d;
int fd=fileno(playback_fd);
/* try to lower the DSP delay; this ioctl may fail gracefully */
......@@ -181,13 +181,13 @@ void *playback_thread(void *dummy){
struct timeval tv;
long foo;
gettimeofday(&tv,NULL);
foo=tv.tv_sec*10+tv.tv_usec/100000;
foo=tv.tv_sec*20+tv.tv_usec/50000;
if(last!=foo)
write(eventpipe[1],"",1);
last=foo;
}
count+=fwrite(audiobuf,1,audiobufsize,playback_fd);
count+=fwrite(audiobuf,1,ret->channels*ret->samples*2,playback_fd);
}
}
......
......@@ -59,10 +59,6 @@
#include "envelope.h"
#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
#define fromdB(x) (exp((x)*.11512925f))
#define toOC(n) (log(n)*1.442695f-5.965784f)
#define MAX_BLOCKSIZE 32768
#define BANDS 35
......@@ -2004,7 +2000,7 @@ int main(int argc, char **argv){
form_init(&editf,120,1);
form_init(&noneditf,50,0);
box(stdscr,0,0);
mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.7 2003/10/10 08:02:12 xiphmont Exp $ ");
mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.8 2003/10/14 08:39:08 xiphmont Exp $ ");
mvaddstr(LINES-1, 2,
" [<]<< [,]< [Spc] Play/Pause [Bksp] Stop/Cue [.]> [>]>> ");
......
......@@ -48,6 +48,10 @@
#include <signal.h>
#include <fcntl.h>
#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
#define fromdB(x) (exp((x)*.11512925f))
#define toOC(n) (log(n)*1.442695f-5.965784f)
typedef struct time_linkage {
int samples;
int channels;
......@@ -64,4 +68,5 @@ extern int outfileno;
extern int seekable;
extern int eventpipe[2];
extern int input_ch;
extern sig_atomic_t input_feedback;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment