Commit 6beba8b4 authored by Monty Montgomery's avatar Monty Montgomery

Bugfix:
small difference in x aligmnent calculation in multibar meant slider occasionally did not align with scale. Fixed.

Improvements:
Do not perform pixmap updates/feedback calculation when a panel is not mapped.

Throw away pixmap updates/exposes if display thread is lagging behind
computation (avoid UI being permanently behind playback and ignoring
user input)


git-svn-id: https://svn.xiph.org/trunk/postfish@5847 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 7e90e987
......@@ -31,6 +31,7 @@
#include "declip.h"
extern sig_atomic_t declip_active;
extern sig_atomic_t declip_visible;
extern int input_ch;
extern int input_size;
extern int input_rate;
......@@ -115,7 +116,7 @@ void clippanel_create(postfish_mainpanel *mp,
int block_choices=0;
subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
&declip_active,
&declip_active,&declip_visible,
"_Declipping filter setup"," [d] ");
GtkWidget *framebox=gtk_hbox_new(1,0);
......@@ -317,7 +318,7 @@ void clippanel_create(postfish_mainpanel *mp,
}
void clippanel_feedback(void){
void clippanel_feedback(int displayit){
int clip[input_ch],count;
double peak[input_ch];
if(pull_declip_feedback(clip,peak,&count)){
......@@ -327,10 +328,13 @@ void clippanel_feedback(void){
val[0]=-1.,zero[0]=-1.;
val[1]=(count?clip[i]*100./count-.1:-1);
zero[1]=-1.;
multibar_set(MULTIBAR(feedback_bars[i]),zero,val,2);
val[0]=(count?peak[i]:-1);
multibar_set(MULTIBAR(trigger_bars[i]),zero,val,1);
if(displayit && declip_visible){
multibar_set(MULTIBAR(feedback_bars[i]),zero,val,2);
val[0]=(count?peak[i]:-1);
multibar_set(MULTIBAR(trigger_bars[i]),zero,val,1);
}
if(clip[i]){
multibar_setwarn(MULTIBAR(mainpanel_inbar));
......
......@@ -26,5 +26,5 @@
extern void clippanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton);
extern void clippanel_feedback(void);
extern void clippanel_feedback(int workp);
extern void clippanel_reset(void);
/*
*
* postfish
*
* Copyright (C) 2002-2004 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.
*
*
*/
#include "postfish.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "readout.h"
#include "multibar.h"
#include "mainpanel.h"
#include "subpanel.h"
#include "feedback.h"
#include "freq.h"
#include "compand.h"
extern sig_atomic_t compand_active;
extern sig_atomic_t compand_visible;
extern int input_ch;
extern int input_size;
extern int input_rate;
typedef struct {
GtkWidget *slider;
GtkWidget *readoutg;
GtkWidget *readoute;
GtkWidget *readoutc;
int number;
} cbar;
static cbar bars[freqs];
static void slider_change(GtkWidget *w,gpointer in){
char buffer[80];
cbar *b=(cbar *)in;
gdouble val=multibar_get_value(MULTIBAR(b->slider),0);
sprintf(buffer,"%+5.1f dB",val);
readout_set(READOUT(b->readoutg),buffer);
compand_g_set(b->number,val);
val=multibar_get_value(MULTIBAR(b->slider),1);
sprintf(buffer,"%+5.1f dB",val);
readout_set(READOUT(b->readoute),buffer);
compand_e_set(b->number,val);
val=multibar_get_value(MULTIBAR(b->slider),2);
sprintf(buffer,"%+5.1f dB",val);
readout_set(READOUT(b->readoute),buffer);
compand_c_set(b->number,val);
}
void compandpanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton){
int i;
char *labels[14]={"-130","-120","-110","-100","-90","-80","-70",
"-60","-50","-40","-30","-20","-10","0"};
double levels[15]={-140,-130,-120,-110,-100,-90,-80,-70,-60,-50,-40,
-30,-20,-10,0};
subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
&compand_active,
&compand_visible,
"_Compander and Noise Gate"," [c] ");
GtkWidget *slidertable=gtk_table_new(freqs,5,0);
for(i=0;i<freqs;i++){
const char *labeltext=freq_frequency_label(i);
GtkWidget *label=gtk_label_new(labeltext);
gtk_widget_set_name(label,"smallmarker");
bars[i].readoutg=readout_new("+000 dB");
bars[i].readoute=readout_new("+000 dB");
bars[i].readoutc=readout_new("+000 dB");
bars[i].slider=multibar_new(14,labels,levels,3,
LO_DECAY|HI_DECAY|LO_ATTACK|HI_ATTACK);
bars[i].number=i;
multibar_callback(MULTIBAR(bars[i].slider),slider_change,bars+i);
multibar_thumb_set(MULTIBAR(bars[i].slider),-140.,0);
multibar_thumb_set(MULTIBAR(bars[i].slider),-140.,1);
multibar_thumb_set(MULTIBAR(bars[i].slider),0.,2);
multibar_thumb_bounds(MULTIBAR(bars[i].slider),-140,0);
gtk_misc_set_alignment(GTK_MISC(label),1,.5);
gtk_table_attach(GTK_TABLE(slidertable),label,0,1,i,i+1,
GTK_FILL,0,10,0);
gtk_table_attach(GTK_TABLE(slidertable),bars[i].readout,2,3,i,i+1,
GTK_FILL,0,0,0);
gtk_table_attach(GTK_TABLE(slidertable),bars[i].readout,3,4,i,i+1,
GTK_FILL,0,0,0);
gtk_table_attach(GTK_TABLE(slidertable),bars[i].readout,4,5,i,i+1,
GTK_FILL,0,0,0);
gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,1,2,i,i+1,
GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,0,0);
}
gtk_box_pack_start(GTK_BOX(panel->subpanel_box),slidertable,1,1,4);
}
static double **peakfeed=0;
static double **rmsfeed=0;
void compandpanel_feedback(int displayit){
int i;
if(!peakfeed){
peakfeed=malloc(sizeof(*peakfeed)*freqs);
rmsfeed=malloc(sizeof(*rmsfeed)*freqs);
for(i=0;i<freqs;i++){
peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
}
}
if(pull_compand_feedback(peakfeed,rmsfeed)==1)
if(displayit && compand_visible)
for(i=0;i<freqs;i++)
multibar_set(MULTIBAR(bars[i].slider),rmsfeed[i],peakfeed[i],input_ch);
}
void compandpanel_reset(void){
int i;
for(i=0;i<freqs;i++)
multibar_reset(MULTIBAR(bars[i].slider));
}
......@@ -50,6 +50,7 @@ static time_linkage out;
/* accessed across threads */
sig_atomic_t declip_active=0;
sig_atomic_t declip_visible=0;
sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
static double *chtrigger=0;
......
......@@ -30,6 +30,7 @@
extern int input_size;
sig_atomic_t eq_active;
sig_atomic_t eq_visible;
freq_state eq;
......@@ -85,5 +86,5 @@ static void workfunc(double *data,freq_state *f,
/* called only by playback thread */
time_linkage *eq_read(time_linkage *in){
return freq_read(in,&eq,workfunc);
return freq_read(in,&eq,workfunc,!(eq_visible||eq_active));
}
......@@ -33,6 +33,7 @@
#include "eq.h"
extern sig_atomic_t eq_active;
extern sig_atomic_t eq_visible;
extern int input_ch;
extern int input_size;
extern int input_rate;
......@@ -43,7 +44,7 @@ typedef struct {
int number;
} bar;
bar bars[freqs];
static bar bars[freqs];
static void slider_change(GtkWidget *w,gpointer in){
char buffer[80];
......@@ -68,6 +69,7 @@ void eqpanel_create(postfish_mainpanel *mp,
subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
&eq_active,
&eq_visible,
"_Equalization filter"," [e] ");
GtkWidget *slidertable=gtk_table_new(freqs,3,0);
......@@ -104,7 +106,7 @@ void eqpanel_create(postfish_mainpanel *mp,
static double **peakfeed=0;
static double **rmsfeed=0;
void eqpanel_feedback(void){
void eqpanel_feedback(int displayit){
int i;
if(!peakfeed){
peakfeed=malloc(sizeof(*peakfeed)*freqs);
......@@ -116,10 +118,10 @@ void eqpanel_feedback(void){
}
}
if(pull_eq_feedback(peakfeed,rmsfeed))
for(i=0;i<freqs;i++)
multibar_set(MULTIBAR(bars[i].slider),rmsfeed[i],peakfeed[i],input_ch);
if(pull_eq_feedback(peakfeed,rmsfeed)==1)
if(displayit && eq_visible)
for(i=0;i<freqs;i++)
multibar_set(MULTIBAR(bars[i].slider),rmsfeed[i],peakfeed[i],input_ch);
}
void eqpanel_reset(void){
......
......@@ -25,5 +25,5 @@
extern void eqpanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton);
extern void eqpanel_feedback(void);
extern void eqpanel_feedback(int workp);
extern void eqpanel_reset(void);
......@@ -83,3 +83,17 @@ void feedback_old(feedback_generic_pool *pool,
pthread_mutex_unlock(&master_mutex);
}
/* are there multiple feedback outputs waiting or just one (a metric
of 'are we behind?') */
int feedback_deep(feedback_generic_pool *pool){
if(pool){
pthread_mutex_lock(&master_mutex);
if(pool->feedback_list_tail)
if(pool->feedback_list_tail->next){
pthread_mutex_unlock(&master_mutex);
return 1;
}
pthread_mutex_unlock(&master_mutex);
}
return 0;
}
......@@ -38,4 +38,5 @@ extern void feedback_push(feedback_generic_pool *pool,
extern feedback_generic *feedback_pull(feedback_generic_pool *pool);
extern void feedback_old(feedback_generic_pool *pool,
feedback_generic *f);
extern int feedback_deep(feedback_generic_pool *pool);
......@@ -27,38 +27,6 @@
#include "feedback.h"
#include "freq.h"
#include <stdio.h>
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(bark){
float b=toBark((4000.f*j/n)+.25);
fprintf(of,"%f ",b);
}else
fprintf(of,"%f ",(double)j);
if(dB){
if(j==0||j==n-1)
fprintf(of,"%f\n",todB(v[j]));
else{
fprintf(of,"%f\n",todB(hypot(v[j],v[j+1])));
j++;
}
}else{
fprintf(of,"%f\n",v[j]);
}
}
fclose(of);
}
extern int input_rate;
extern int input_ch;
extern int input_size;
......@@ -68,6 +36,7 @@ typedef struct freq_feedback{
feedback_generic parent_class;
double **peak;
double **rms;
int bypass;
} freq_feedback;
/* accessed only in playback thread/setup */
......@@ -108,18 +77,22 @@ int pull_freq_feedback(freq_state *ff,double **peak,double **rms){
if(!f)return 0;
if(peak)
for(i=0;i<freqs;i++)
for(j=0;j<input_ch;j++)
peak[i][j]=f->peak[j][i];
if(rms)
for(i=0;i<freqs;i++)
for(j=0;j<input_ch;j++)
rms[i][j]=f->rms[j][i];
feedback_old(&ff->feedpool,(feedback_generic *)f);
return 1;
if(f->bypass){
feedback_old(&ff->feedpool,(feedback_generic *)f);
return 2;
}else{
if(peak)
for(i=0;i<freqs;i++)
for(j=0;j<input_ch;j++)
peak[i][j]=f->peak[j][i];
if(rms)
for(i=0;i<freqs;i++)
for(j=0;j<input_ch;j++)
rms[i][j]=f->rms[j][i];
feedback_old(&ff->feedpool,(feedback_generic *)f);
return 1;
}
}
/* called only by initial setup */
......@@ -285,9 +258,6 @@ static void feedback_work(double *peak,double *rms,
static void lap_work(double *work,double *lap,double *out,freq_state *f){
double *workoff=work+f->blocksize/2;
int i,j;
/* back to time we go */
drft_backward(&f->fft,work);
/* lap and out */
if(out)
......@@ -303,7 +273,8 @@ static void lap_work(double *work,double *lap,double *out,freq_state *f){
/* called only by playback thread */
time_linkage *freq_read(time_linkage *in, freq_state *f,
void (*func)(double *data,freq_state *f,
double *peak, double *rms)){
double *peak, double *rms),
int bypass){
int i;
double feedback_peak[input_ch][freqs];
......@@ -314,9 +285,10 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
int blocks=0;
memset(feedback_peak,0,sizeof(feedback_peak));
memset(feedback_rms,0,sizeof(feedback_rms));
if(!bypass){
memset(feedback_peak,0,sizeof(feedback_peak));
memset(feedback_rms,0,sizeof(feedback_rms));
}
{
double work[f->blocksize*2];
......@@ -333,9 +305,12 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
memset(work+f->blocksize/2,0,sizeof(*work)*f->blocksize/2);
memcpy(work+f->blocksize,temp,sizeof(*work)*f->blocksize/2);
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
if(!bypass){
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
drft_backward(&f->fft,work);
}
lap_work(work,f->lap[i],0,f);
blocks++;
......@@ -362,9 +337,12 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
memcpy(work+f->blocksize/2,temp+j,sizeof(*work)*f->blocksize);
memset(work+f->blocksize*3/2,0,sizeof(*work)*f->blocksize/2);
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
if(!bypass){
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
drft_backward(&f->fft,work);
}
lap_work(work,f->lap[i],f->out.data[i]+j,f);
blocks++;
}
......@@ -374,9 +352,12 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
memcpy(work+f->blocksize,in->data[i],sizeof(*work)*f->blocksize/2);
memset(work+f->blocksize*3/2,0,sizeof(*work)*f->blocksize/2);
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
if(!bypass){
transform_work(work,f);
func(work,f,peak,rms);
feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
drft_backward(&f->fft,work);
}
lap_work(work,f->lap[i],f->out.data[i]+j,f);
blocks++;
......@@ -394,7 +375,7 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
/* finish up the state feedabck */
blocks/=input_ch;
{
if(!bypass){
int j;
double scale=1./blocks;
freq_feedback *ff=
......@@ -410,6 +391,12 @@ time_linkage *freq_read(time_linkage *in, freq_state *f,
memcpy(ff->peak[i],feedback_peak[i],freqs*sizeof(**feedback_peak));
memcpy(ff->rms[i],feedback_rms[i],freqs*sizeof(**feedback_rms));
}
ff->bypass=0;
feedback_push(&f->feedpool,(feedback_generic *)ff);
}else{
freq_feedback *ff=
(freq_feedback *)feedback_new(&f->feedpool,new_freq_feedback);
ff->bypass=1;
feedback_push(&f->feedpool,(feedback_generic *)ff);
}
......
......@@ -52,7 +52,8 @@ extern int freq_reset(freq_state *f);
extern const char *freq_frequency_label(int n);
extern time_linkage *freq_read(time_linkage *in, freq_state *f,
void (*func)(double *data,freq_state *f,
double *peak, double *rms));
double *peak, double *rms),
int bypassp);
extern void freq_metric_work(double *work,freq_state *f,
double *sq_mags,double *peak,double *rms);
......@@ -587,7 +587,7 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
panel->leftframe=gtk_frame_new(NULL);
panel->box2=gtk_vbox_new(0,0);
panel->box1=gtk_vbox_new(0,6);
panel->wintable=gtk_table_new(7,3,0);
panel->wintable=gtk_table_new(6,3,0);
panel->twirlimage=gtk_image_new_from_pixmap(panel->ff[0],panel->fb[0]);
gtk_container_set_border_width (GTK_CONTAINER (panel->topframe), 3);
......@@ -854,11 +854,10 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
mainpanel_panelentry(panel,"_Declip ","[d]",0,clippanel_create);
mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0);
mainpanel_panelentry(panel,"_Noise Filter ","[n]",2,0);
mainpanel_panelentry(panel,"_Compand/Gate ","[c]",2,0);
mainpanel_panelentry(panel,"_Equalizer ","[e]",3,eqpanel_create);
mainpanel_panelentry(panel,"_Compander ","[c]",4,0);
mainpanel_panelentry(panel,"_Limiter ","[l]",5,0);
mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0);
mainpanel_panelentry(panel,"_Limiter ","[l]",4,0);
mainpanel_panelentry(panel,"_Output Cal. ","[o]",5,0);
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
......@@ -885,30 +884,24 @@ static gboolean feedback_process(postfish_mainpanel *panel){
/* second order of business; update the input meter if data is
available and not dirtied by a seek */
if(!playback_seeking){
off_t time_cursor;
int n=(input_ch>1?input_ch+2:input_ch);
double *rms=alloca(sizeof(*rms)*(input_ch+2));
double *peak=alloca(sizeof(*peak)*(input_ch+2));
if(pull_output_feedback(peak,rms)){
char buffer[14];
int i;
for(i=0;i<n;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;
}
if(output_feedback_deep()){
if(i<input_ch && peak[i]>=0.)multibar_setwarn(MULTIBAR(panel->outbar));
}
multibar_set(MULTIBAR(panel->outbar),rms,peak,n);
pull_input_feedback(NULL,NULL,NULL);
clippanel_feedback(0);
eqpanel_feedback(0);
pull_output_feedback(NULL,NULL);
if(pull_input_feedback(peak,rms,&time_cursor)){
}else{
off_t time_cursor;
int n=(input_ch>1?input_ch+2:input_ch);
double *rms=alloca(sizeof(*rms)*(input_ch+2));
double *peak=alloca(sizeof(*peak)*(input_ch+2));
if(pull_output_feedback(peak,rms)){
char buffer[14];
int i;
for(i=0;i<n;i++){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->channelshow[i]))){
peak[i]=todB(peak[i]);
......@@ -917,16 +910,32 @@ static gboolean feedback_process(postfish_mainpanel *panel){
peak[i]=-400;
rms[i]=-400;
}
if(i<input_ch && peak[i]>=0.)multibar_setwarn(MULTIBAR(panel->outbar));
}
multibar_set(MULTIBAR(panel->outbar),rms,peak,n);
if(pull_input_feedback(peak,rms,&time_cursor)){
for(i=0;i<n;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,n);
input_cursor_to_time(time_cursor,buffer);
readout_set(READOUT(panel->cue),buffer);
}
multibar_set(MULTIBAR(panel->inbar),rms,peak,n);
input_cursor_to_time(time_cursor,buffer);
readout_set(READOUT(panel->cue),buffer);
clippanel_feedback(1);
eqpanel_feedback(1);
}
clippanel_feedback();
eqpanel_feedback();
}
}
......
......@@ -355,7 +355,7 @@ static void draw(GtkWidget *widget,int n){
}
for(i=0;i<m->labels+1;i++){
int x=rint(((double)i)/m->labels*(widget->allocation.width-xpad*2)+xpad);
int x=rint(((double)i)/m->labels*(widget->allocation.width-xpad*2))+xpad);
int y=widget->allocation.height-lpad-upad;
int px,py;
int gc=0;
......
......@@ -92,6 +92,9 @@ int pull_output_feedback(double *peak,double *rms){
return 1;
}
int output_feedback_deep(void){
return feedback_deep(&feedpool);
}
static void PutNumLE(long num,FILE *f,int bytes){
int i=0;
......
......@@ -3,3 +3,4 @@ extern void *playback_thread(void *dummy);
extern void output_halt_playback(void);
extern void output_reset(void);
extern void playback_request_seek(off_t cursor);
extern int output_feedback_deep(void);
......@@ -32,9 +32,11 @@ static int clippanel_hide(GtkWidget *widget,
GdkEvent *event,
gpointer in){
subpanel_generic *p=in;
if(p->mappedvar)*p->mappedvar=0;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),0);
return TRUE;
}
static int windowbutton_action(GtkWidget *widget,
gpointer in){
int active;
......@@ -47,10 +49,13 @@ static int windowbutton_action(GtkWidget *widget,
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),active);
}
if(active)
if(active){
if(p->mappedvar)*p->mappedvar=1;
gtk_widget_show_all(p->subpanel_toplevel);
else
}else{
if(p->mappedvar)*p->mappedvar=0;
gtk_widget_hide_all(p->subpanel_toplevel);
}
return FALSE;
}
......@@ -103,6 +108,7 @@ subpanel_generic *subpanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton,
sig_atomic_t *activevar,
sig_atomic_t *mappedvar,
char *prompt,char *shortcut){
subpanel_generic *panel=calloc(1,sizeof(*panel));
......@@ -124,6 +130,7 @@ subpanel_generic *subpanel_create(postfish_mainpanel *mp,
panel->mainpanel_windowbutton=windowbutton;
panel->mainpanel_activebutton=activebutton;
panel->activevar=activevar;
panel->mappedvar=mappedvar;
gtk_box_pack_start(GTK_BOX(toplabel),toplabelwb,0,0,5);
gtk_box_pack_end(GTK_BOX(toplabel),toplabelab,0,0,5);
......