Commit 5ddc2e13 authored by Monty Montgomery's avatar Monty Montgomery

It may just be a side project... but don't lose it :-)


git-svn-id: https://svn.xiph.org/trunk/postfish@5339 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent e9384ee0
# Fuck Automake
# Fuck the horse it rode in on
# and Fuck its little dog Libtool too
CC=gcc
LD=gcc
SRC = mainpanel.c multibar.c
OBJ = mainpanel.o multibar.o
GCF = `pkg-config --cflags gtk+-2.0`
all:
$(MAKE) target CFLAGS="-W -O2 $(GCF)"
debug:
$(MAKE) target CFLAGS="-g -W -D__NO_MATH_INLINES $(GCF)"
profile:
$(MAKE) target CFLAGS="-W -pg -g -O2 $(GCF)"
clean:
rm -f $(OBJ) *.d
%.d: %.c
$(CC) -M $(GCF) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$
include $(SRC:.c=.d)
target: $(OBJ)
$(LD) $(OBJ) $(CFLAGS) -o postfish `pkg-config --libs gtk+-2.0` -lpthread -lm
......@@ -9,7 +9,7 @@ LDADD = -lm -lpthread -lncurses
bin_PROGRAMS = postfish
man_MANS = postfish.1
postfish_SOURCES = postfish.c smallft.c form.c smallft.h form.h
postfish_SOURCES = postfish.c smallft.c form.c envelope.c envelope.h smallft.h form.h
postfish_LDADD = $(LDADD)
debug:
......
This diff is collapsed.
......@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <ncurses.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
#include <form.h>
......
#include <gtk/gtk.h>
#include "fisharray.h"
#include "multibar.h"
#define VERSION "$Id: mainpanel.c,v 1.1 2003/09/16 08:55:12 xiphmont Exp $"
typedef struct {
GtkWidget *toplevel;
GtkWidget *topframe;
GtkWidget *toplabel;
GtkWidget *mainbox;
GtkWidget *leftbox;
GtkWidget *panelframe;
GtkWidget *rightbox;
GtkWidget *wintable;
GtkWidget *twirlimage;
GdkPixmap *ff[12];
GdkBitmap *fb[12];
GtkWidget *buttonpanel[7];
GtkWidget *buttonactive[7];
GtkWidget *quitbutton;
} postfish_mainpanel;
static void shutdown(void){
gtk_main_quit ();
}
static void mainpanel_panelentry(postfish_mainpanel *p,
char *label,
char *shortcut,
int i){
p->buttonpanel[i]=gtk_check_button_new_with_mnemonic(label);
p->buttonactive[i]=gtk_toggle_button_new_with_label(shortcut);
gtk_table_attach_defaults(GTK_TABLE(p->wintable),p->buttonpanel[i],0,1,i+1,i+2);
gtk_table_attach_defaults(GTK_TABLE(p->wintable),p->buttonactive[i],1,2,i+1,i+2);
}
void mainpanel_create(postfish_mainpanel *panel){
int i;
GdkWindow *root=gdk_get_default_root_window();
panel->toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
panel->topframe=gtk_frame_new (NULL);
panel->toplabel=gtk_label_new (NULL);
for(i=0;i<12;i++)
panel->ff[i]=gdk_pixmap_create_from_xpm_d(root,
panel->fb+i,NULL,ff_xpm[i]);
panel->mainbox=gtk_hbox_new(0,0);
panel->leftbox=gtk_vbox_new(0,0);
panel->rightbox=gtk_vbox_new(0,0);
panel->wintable=gtk_table_new(8,2,0);
panel->twirlimage=gtk_image_new_from_pixmap(panel->ff[0],panel->fb[0]);
gtk_container_set_border_width (GTK_CONTAINER (panel->topframe), 3);
gtk_container_set_border_width (GTK_CONTAINER (panel->mainbox), 3);
gtk_frame_set_shadow_type(GTK_FRAME(panel->topframe),GTK_SHADOW_ETCHED_IN);
gtk_frame_set_label_widget(GTK_FRAME(panel->topframe),panel->toplabel);
gtk_label_set_markup(GTK_LABEL(panel->toplabel),
"<span size=\"large\" weight=\"bold\" "
"style=\"italic\" foreground=\"dark blue\">"
"Postfish</span> "VERSION);
gtk_container_add (GTK_CONTAINER (panel->toplevel), panel->topframe);
gtk_container_add (GTK_CONTAINER(panel->topframe), panel->mainbox);
gtk_box_pack_start(GTK_BOX(panel->mainbox),panel->leftbox,0,0,0);
gtk_box_pack_end(GTK_BOX(panel->mainbox),panel->rightbox,1,1,0);
/* left side of main panel */
{
GtkWidget *tempf=gtk_frame_new(NULL);
GtkWidget *temp=gtk_table_new(1,1,0);
GtkWidget *tempa=gtk_alignment_new(0,1,0,0);
gtk_frame_set_shadow_type(GTK_FRAME(tempf),GTK_SHADOW_ETCHED_IN);
gtk_container_set_border_width (GTK_CONTAINER (tempf), 3);
gtk_box_pack_end(GTK_BOX(panel->leftbox),temp,0,0,0);
gtk_container_add (GTK_CONTAINER(tempf), panel->twirlimage);
panel->quitbutton=gtk_button_new_with_mnemonic("quit");
gtk_widget_set_name(panel->quitbutton,"quitbutton");
gtk_container_add(GTK_CONTAINER(tempa),panel->quitbutton);
gtk_table_attach_defaults(GTK_TABLE(temp),tempa,0,1,0,1);
gtk_table_attach_defaults(GTK_TABLE(temp),tempf,0,1,0,1);
}
panel->panelframe=gtk_frame_new(NULL);
gtk_container_set_border_width (GTK_CONTAINER (panel->panelframe), 3);
gtk_container_set_border_width (GTK_CONTAINER (panel->wintable), 3);
gtk_box_pack_start(GTK_BOX(panel->leftbox),panel->panelframe,0,0,0);
gtk_frame_set_shadow_type(GTK_FRAME(panel->panelframe),GTK_SHADOW_ETCHED_IN);
gtk_container_add(GTK_CONTAINER(panel->panelframe),panel->wintable);
gtk_table_set_row_spacings(GTK_TABLE(panel->wintable),1);
{
GtkWidget *temp=gtk_label_new("visible");
gtk_misc_set_alignment(GTK_MISC(temp),0,.5);
gtk_table_attach_defaults(GTK_TABLE(panel->wintable),temp,0,1,0,1);
temp=gtk_label_new("active");
gtk_misc_set_alignment(GTK_MISC(temp),1,.5);
gtk_table_attach_defaults(GTK_TABLE(panel->wintable),temp,1,2,0,1);
}
mainpanel_panelentry(panel,"_Declip ","d",0);
mainpanel_panelentry(panel,"Cross_Talk ","t",1);
mainpanel_panelentry(panel,"_Noise Filter ","n",2);
mainpanel_panelentry(panel,"_Equalizer ","e",3);
mainpanel_panelentry(panel,"_Compander ","c",4);
mainpanel_panelentry(panel,"_Limiter ","l",5);
mainpanel_panelentry(panel,"Cue_Sheet ","s",6);
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
g_signal_connect (G_OBJECT (panel->quitbutton), "clicked",
G_CALLBACK (shutdown), NULL);
/* 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};
GtkWidget *temp=multibar_new(12,labels,levels);
gtk_box_pack_start(GTK_BOX(panel->rightbox),temp,0,0,0);
}
gtk_widget_show_all(panel->toplevel);
}
#include <stdlib.h>
int main(int argc, char *argv[]){
postfish_mainpanel mainpanel;
char *homedir=getenv("HOME");
gtk_rc_add_default_file("/etc/postfish/postfishrc");
if(homedir){
char *rcfile="/.postfishrc";
char *homerc=calloc(1,strlen(homedir)+strlen(rcfile)+1);
strcat(homerc,homedir);
strcat(homerc,rcfile);
gtk_rc_add_default_file(homerc);
}
gtk_init (&argc, &argv);
mainpanel_create(&mainpanel);
gtk_main ();
}
#include <stdio.h>
#include <stdlib.h>
#include "multibar.h"
static void draw(GtkWidget *widget,float *lowvals, float *highvals, int n){
int i,j;
Multibar *m=MULTIBAR(widget);
float max=lowvals[0];
if(!m->boxcolor){
m->boxcolor=gdk_gc_new(m->backing);
gdk_gc_copy(m->boxcolor,widget->style->black_gc);
}
if(m->cliptimer.tv_sec){
struct timeval tv;
gettimeofday(&tv,NULL);
long val=(tv.tv_sec-m->cliptimer.tv_sec)*1000+(tv.tv_usec-m->cliptimer.tv_usec)/1000;
if(val>2000)memset(&m->cliptimer,0,sizeof(m->cliptimer));
}
if(m->peaktimer.tv_sec){
struct timeval tv;
gettimeofday(&tv,NULL);
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;
}
for(i=0;i<n;i++)
if(highvals[i]>=0.){
gettimeofday(&m->cliptimer,NULL);
break;
}
for(i=0;i<n;i++)
if(highvals[i]>max)max=highvals[i];
if(max>m->peak){
m->peak=max;
gettimeofday(&m->peaktimer,NULL);
}
{
int x=-1;
int *pixhi=alloca(n*sizeof(*pixhi));
int *pixlo=alloca(n*sizeof(*pixlo));
for(i=0;i<n;i++){
pixlo[i]=-1;
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]);
pixlo[i]=(j+del)/m->labels*widget->allocation.width;
break;
}
}else
break;
pixhi[i]=pixlo[i];
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]);
pixhi[i]=(j+del)/m->labels*widget->allocation.width;
break;
}
}else
break;
}
while(x<widget->allocation.width){
int r=0xffff,g=0xffff,b=0xffff;
GdkColor rgb={0,0,0,0};
int next=widget->allocation.width;
for(i=0;i<n;i++){
if(pixlo[i]>x && pixlo[i]<next)next=pixlo[i];
if(pixhi[i]>x && pixhi[i]<next)next=pixhi[i];
}
if(m->cliptimer.tv_sec!=0){
g=0x6000;
b=0x6000;
}
for(i=0;i<n;i++){
if(pixlo[i]<=x && pixhi[i]>=next){
switch(i%8){
case 0:
r*=.55;
g*=.55;
b*=.55;
break;
case 1:
r*=.8;
g*=.5;
b*=.5;
break;
case 2:
r*=.6;
g*=.6;
b*=.9;
break;
case 3:
r*=.4;
g*=.7;
b*=.4;
break;
case 4:
r*=.6;
g*=.5;
b*=.3;
break;
case 5:
r*=.6;
g*=.4;
b*=.7;
break;
case 6:
r*=.3;
g*=.6;
b*=.6;
break;
case 7:
r*=.4;
g*=.4;
b*=.4;
break;
}
}
}
rgb.red=r;
rgb.green=g;
rgb.blue=b;
gdk_gc_set_rgb_fg_color(m->boxcolor,&rgb);
gdk_draw_rectangle(m->backing,m->boxcolor,1,x+1,1,next-x,widget->allocation.height-2);
x=next;
}
}
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]);
}
/* peak follower */
{
int x=-10;
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]);
x=(j+del)/m->labels*widget->allocation.width;
break;
}
}else
break;
gdk_draw_polygon(m->backing,widget->style->black_gc,1,
(GdkPoint[]){{x,5},{x+5,0},{x-4,0}},3);
gdk_draw_polygon(m->backing,widget->style->black_gc,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);
}
}
static gboolean configure(GtkWidget *widget, GdkEventConfigure *event){
Multibar *m=MULTIBAR(widget);
if (m->backing)
gdk_pixmap_unref(m->backing);
m->backing = gdk_pixmap_new(widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
gdk_draw_rectangle(m->backing,widget->style->white_gc,1,0,0,widget->allocation.width,
widget->allocation.height);
{
float lo[]={-24,-72};
float hi[]={-7,-10};
draw(widget,lo,hi,2);
}
return TRUE;
}
static gboolean expose( GtkWidget *widget, GdkEventExpose *event ){
Multibar *m=MULTIBAR(widget);
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
m->backing,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
static void size_request (GtkWidget *widget,GtkRequisition *requisition){
int i,maxx=0,maxy=0,x,y;
Multibar *m=MULTIBAR(widget);
for(i=0;i<m->labels;i++){
pango_layout_get_pixel_size(m->layout[i],&x,&y);
if(x>maxx)maxx=x;
if(y>maxy)maxy=y;
}
requisition->width = (maxx*2)*m->labels;
requisition->height = maxy;
}
static void multibar_class_init (MultibarClass *class){
GtkWidgetClass *widget_class;
widget_class = (GtkWidgetClass*) class;
widget_class->expose_event = expose;
widget_class->configure_event = configure;
widget_class->size_request = size_request;
//widget_class->button_press_event = gtk_dial_button_press;
//widget_class->button_release_event = gtk_dial_button_release;
//widget_class->motion_notify_event = gtk_dial_motion_notify;
}
static void multibar_init (Multibar *m){
m->layout=0;
m->peak=-200;
m->peaktimer=(struct timeval){0,0};
m->cliptimer=(struct timeval){0,0};
}
GType multibar_get_type (void){
static GType m_type = 0;
if (!m_type){
static const GTypeInfo m_info={
sizeof (MultibarClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) multibar_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (Multibar),
0,
(GInstanceInitFunc) multibar_init,
0
};
m_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, "Multibar", &m_info, 0);
}
return m_type;
}
GtkWidget* multibar_new (int n, char **labels, float *levels){
int i;
GtkWidget *ret= GTK_WIDGET (g_object_new (multibar_get_type (), NULL));
Multibar *m=MULTIBAR(ret);
/* not the *proper* way to do it, but this is a one-shot */
m->levels=calloc((n+1),sizeof(*m->levels));
m->labels=n;
memcpy(m->levels,levels,(n+1)*sizeof(*levels));
m->layout=calloc(m->labels,sizeof(*m->layout));
for(i=0;i<m->labels;i++)
m->layout[i]=gtk_widget_create_pango_layout(ret,labels[i]);
return ret;
}
void multibar_set(Multibar *m,float *lo, float *hi, int n){
GtkWidget *widget=GTK_WIDGET(m);
draw(widget,lo,hi,n);
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
m->backing,
0, 0,
0, 0,
widget->allocation.width,
widget->allocation.height);
}
#ifndef __MULTIBAR_H__
#define __MULTIBAR_H__
#include <sys/time.h>
#include <time.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtkcontainer.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdrawingarea.h>
G_BEGIN_DECLS
#define MULTIBAR_TYPE (multibar_get_type ())
#define MULTIBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MULTIBAR_TYPE, Multibar))
#define MULTIBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MULTIBAR_TYPE, MultibarClass))
#define IS_MULTIBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MULTIBAR_TYPE))
#define IS_MULTIBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MULTIBAR_TYPE))
typedef struct _Multibar Multibar;
typedef struct _MultibarClass MultibarClass;
struct _Multibar{
GtkDrawingArea canvas;
GdkPixmap *backing;
int labels;
PangoLayout **layout;
float *levels;
GdkGC *boxcolor;
float peak;
struct timeval cliptimer;
struct timeval peaktimer;
};
struct _MultibarClass{
GtkDrawingAreaClass parent_class;
void (* multibar) (Multibar *m);
};
GType multibar_get_type (void);
GtkWidget* multibar_new (int n, char **labels, float *levels);
void multibar_clear (Multibar *m);
void multibar_set (Multibar *m,float *lo,float *hi, int n);
G_END_DECLS
#endif
......@@ -57,6 +57,8 @@
#include <smallft.h>
#include <form.h>
#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)
......@@ -65,6 +67,7 @@
#define BANDS 35
static int outfileno=-1;
static int loop_flag=1;
static int inbytes=0;
static int outbytes=2;
static int rate=0;
......@@ -188,6 +191,7 @@ pthread_mutex_t master_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
int playback_active=0;
int playback_exit=0;
drft_lookup fft;
env_lookup envpre,envpost;
pthread_t playback_thread_id;
......@@ -450,7 +454,7 @@ off_t time_to_cursor(long t){
off_t c=t%10000;
c+=t/10000%100*6000;
c+=t/1000000*600000;
c+=t/1000000*6000*60;
return((off_t)rint(c*.01*rate)*ch*inbytes);
}
......@@ -468,8 +472,10 @@ long cursor_to_time(off_t c){
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;
c%=(100*60*60);
T+=c/(100*60)*10000;
c%= (100*60);
T+=c/(100)*100;
T+=c%100;
return(T);
}
......@@ -993,6 +999,57 @@ void dynamic_att(double *b){
pthread_mutex_unlock(&master_mutex);
}
void dynamic_sq(double *b){
int i;
pthread_mutex_lock(&master_mutex);
if(wc.dynamicatt_p && wc.dynamicatt!=0.){
double diff=fromdB(wc.dynamicatt/10.);
pthread_mutex_unlock(&master_mutex);
env_compute(&envpre,b);
/* zero */
{
double val=diff*envpre.envelope[0];
double M=b[0];
if(M-val>0){
double div=(M-val)/M;
b[0]*=div;
}else{
b[0]=0;
}
}
/* 1 ... n-1 */
for(i=1;i+1<block-1;i+=2){
double val=diff*envpre.envelope[(i>>1)+1];
double M=hypot(b[i],b[i+1]);
if(M-val>0){
double div=(M-val)/M;
b[i]*=div;
b[i+1]*=div;
}else{
b[i]=0;
b[i+1]=0;
}
}
/* n */
{
double val=diff*envpre.envelope[block/2-1];
double M=b[block/2-1];
if(M-val>0){
double div=(M-val)/M;
b[block/2-1]*=div;
}else{
b[block/2-1]=0;
}
}
}else
pthread_mutex_unlock(&master_mutex);
}
void refresh_thresh_array(double *t,long *set){
int i;
for(i=0;i<=block/2;i++){
......@@ -1228,7 +1285,12 @@ int aread(double **buf){
}
if(Bcursor!=-1 && cursor>=Bcursor){
aseek(Acursor);
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++;
......@@ -1309,6 +1371,40 @@ int isachr(FILE *f){
return 0;
}
#define toBark(n) \
(13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
#define fromdB(x) (exp((x)*.11512925f))
void _analysis(char *base,int i,double *v,int n,int bark,int dB){
int j;
FILE *of;
char buffer[80];
sprintf(buffer,"%s_%d.m",base,i);
of=fopen(buffer,"w");
if(!of)perror("failed to open data dump file");
for(j=0;j<n;j++){
if(!dB || v[j]!=0){
if(bark)
fprintf(of,"%f ",toBark(22050.f*j/n));
else
fprintf(of,"%f ",(double)j);
if(dB){
fprintf(of,"%.12f\n",todB(v[j]));
}else{
fprintf(of,"%.12f\n",v[j]);
}