⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundspec.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
    make_logspectrogram(values, work);    set_draw_pixel(work, pixels);    expose = 0;    nze = 0;    while(QLength(disp) || XPending(disp))    {	XNextEvent(disp, &e);	switch(e.type)	{	  case Expose:	    expose++;	    break;	  case KeyPress:	    k = xlookup_key(&e.xkey);	    switch(k)	    {#ifdef XK_Down	      case XK_Up:#endif /* XK_Up */#ifdef XK_KP_Up	      case XK_KP_Up:#endif /* XK_KP_Up */		nze++;		break;#ifdef XK_Down	      case XK_Down:#endif /* XK_Down */#ifdef XK_KP_Down	      case XK_KP_Down:#endif /* XK_KP_Down */		nze--;		break;#ifdef XK_Left	      case XK_Left:#endif /* XK_Left */#ifdef XK_KP_Left	      case XK_KP_Left:#endif /* XK_KP_Left */		soundspec_update_interval =		    (int32)(soundspec_update_interval*1.1);		break;#ifdef XK_Right	      case XK_Right:#endif /* XK_Right */#ifdef XK_KP_Right	      case XK_KP_Right:#endif /* XK_KP_Right */		soundspec_update_interval =		    (int32)(soundspec_update_interval/1.1);		if(soundspec_update_interval < 0.01 * play_mode->rate)		    soundspec_update_interval =			(int32)(0.01 * play_mode->rate);		break;	    }	    break;	  case ClientMessage:	    if(wm_delete_window == e.xclient.data.l[0])	    {		mname = XGetAtomName(disp, e.xclient.message_type);		if(mname != NULL && strcmp(mname, "WM_PROTOCOLS") == 0)		{		    /* Delete message from WM */		    ctl->cmsg(CMSG_INFO, VERB_VERBOSE,			      "Sound Spectrogram Window is closed");		    close_soundspec();		    XCloseDisplay(disp);		    disp = NULL;		    return;		}	    }	    break;	}    }    offset = call_cnt % SCROLL_THRESHOLD;    if(offset == 0)    {	XCopyArea(disp, offscr, offscr, gc,		  SCROLL_THRESHOLD, 0,		  SCOPE_WIDTH - SCROLL_THRESHOLD,		  SCOPE_HEIGHT,		  0, 0);	XSetForeground(disp, gc, BlackPixel(disp, DefaultScreen(disp)));	XFillRectangle(disp, offscr, gc,		       SCOPE_WIDTH - SCROLL_THRESHOLD, 0,		       SCROLL_THRESHOLD, SCOPE_HEIGHT);	XCopyArea(disp, offscr, win, gc,		  0, 0, SCOPE_WIDTH, SCOPE_HEIGHT, 0, 0);    }    img->data = (char *)pixels;    XPutImage(disp, offscr, gc, img, 0, 0,	      SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0,	      1, SCOPE_HEIGHT);    if(!expose)	XCopyArea(disp, offscr, win, gc,		  SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0,		  1, SCOPE_HEIGHT, SCOPE_WIDTH - SCROLL_THRESHOLD + offset, 0);    else    {	XCopyArea(disp, offscr, win, gc,		  0, 0, SCOPE_WIDTH, SCOPE_HEIGHT, 0, 0);    }    XSync(disp, False);    if(nze)	initialize_exp_hz_table(soundspec_zoom - 4 * nze);    call_cnt++;}struct drawing_queue{    double values[FFTSIZE/2 + 1];    struct drawing_queue *next;};static struct drawing_queue *free_queue_list = NULL;static struct drawing_queue *new_queue(void){    struct drawing_queue *p;    if(free_queue_list)    {	p = free_queue_list;	free_queue_list = free_queue_list->next;    }    else	p = (struct drawing_queue *)safe_malloc(sizeof(struct drawing_queue));    p->next = NULL;    return p;}static void free_queue(struct drawing_queue *p){    p->next = free_queue_list;    free_queue_list = p;}static void trace_draw_scope(void *vp){    struct drawing_queue *q;    q = (struct drawing_queue *)vp;    if(!midi_trace.flush_flag)    {	if(view_soundspec_flag)	    draw_scope(q->values);	if(ctl_speana_flag)	{	    CtlEvent e;	    e.type = CTLE_SPEANA;	    e.v1 = (long)q->values;	    e.v2 = FFTSIZE/2;	    ctl->event(&e);	}    }    free_queue(q);}static void decibelspec(double *from, double *to){    double p, hr;    int i, j;    static double *w_table = NULL;    if(w_table == NULL)    {	double t;	w_table = (double *)safe_malloc(FFTSIZE * sizeof(double));	t = -M_PI;	for(i = 0; i < FFTSIZE; i++)	{	    w_table[i] = 0.50 + 0.50 * cos(t);	    t += 2.0 * M_PI / FFTSIZE;	}    }    for(i = 0; i < FFTSIZE; i++)	from[i] *= w_table[i];    realfft(from, FFTSIZE);    hr = AMP * NCOLOR;    if(from[0] >= 0)	p = from[0];    else	p = -from[0];    to[0] = log(1.0 + (128.0 / FFTSIZE) * p) * hr;    for(i = 1, j = FFTSIZE - 1; i < FFTSIZE/2; i++, j--)    {	double t, u;	t = from[i];	u = from[j];	to[i] = log(1.0 + (128.0 / FFTSIZE) * sqrt(t*t + u*u)) * hr;    }    p = from[FFTSIZE/2];    to[FFTSIZE/2] = log(1.0 + (128.0 / FFTSIZE) * sqrt(2 * p*p)) * hr;}void close_soundspec(void){    XUnmapWindow(disp, win);    XSync(disp, True); /* Discard all remained X Events */    view_soundspec_flag = 0;}void open_soundspec(void){    int scr;    XGCValues gcv;    if(disp != NULL)    {	XMapWindow(disp, win);	XSync(disp, False);	view_soundspec_flag = 1;	return;    }    if((disp = XOpenDisplay(NULL)) == NULL)    {	ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Can't open display");	ctl->close();	exit(1);    }    set_color_ring();    scr = DefaultScreen(disp);    depth = DefaultDepth(disp, scr);    win = XCreateSimpleWindow(disp, DefaultRootWindow(disp),			      0, 0, SCOPE_WIDTH, SCOPE_HEIGHT,			      0, 0, BlackPixel(disp, scr));    wm_delete_window = XInternAtom(disp, "WM_DELETE_WINDOW", False);    XSetWMProtocols(disp, win, &wm_delete_window, 1);    XSelectInput(disp, win, ExposureMask | KeyPressMask);    XStoreName(disp, win, "Sound Spectrogram");    XSetIconName(disp, win, "Sound Spectrogram");    gcv.graphics_exposures = False;    gc = XCreateGC(disp, win, GCGraphicsExposures, &gcv);    offscr = XCreatePixmap(disp, win, SCOPE_WIDTH, SCOPE_HEIGHT, depth);    XSetForeground(disp, gc, BlackPixel(disp, scr));    XFillRectangle(disp, offscr, gc, 0, 0, SCOPE_WIDTH, SCOPE_HEIGHT);    img = XCreateImage(disp, DefaultVisual(disp, scr),		       depth, ZPixmap, 0, 0,		       1, SCOPE_HEIGHT, 8, 0);    XMapWindow(disp, win);    XSync(disp, False);    view_soundspec_flag = 1;}void soundspec_setinterval(double sec){    soundspec_update_interval = (int32)(sec * play_mode->rate);}static void ringsamples(double *x, int pos, int n){    int i, upper;    double r;    upper = ring_buffer_len;    r = 1.0 / pow(2.0, 32.0);    for(i = 0; i < n; i++, pos++)    {	if(pos >= upper)	    pos = 0;	x[i] = (double)ring_buffer[pos] * r;    }}void soundspec_update_wave(int32 *buff, int samples){    int i;    if(buff == NULL) /* Initialize */    {	ring_index = 0;	if(samples == 0)	{	    outcnt = 0;	    next_wakeup_samples = 0;	}	if(ring_buffer != NULL)	    memset(ring_buffer, 0, sizeof(int32));	return;    }    if(!view_soundspec_flag && !ctl_speana_flag)    {	outcnt += samples;	return;    }    if(ring_buffer == NULL)    {	ring_buffer = safe_malloc(ring_buffer_len * sizeof(int32));	memset(ring_buffer, 0, sizeof(int32));	if(soundspec_update_interval == 0)	    soundspec_update_interval =		(int32)(DEFAULT_UPDATE * play_mode->rate);	realfft(NULL, FFTSIZE);	initialize_exp_hz_table(soundspec_zoom);    }    if(ring_index + samples > ring_buffer_len)    {	int d;	d = ring_buffer_len - ring_index;	if(play_mode->encoding & PE_MONO)	    memcpy(ring_buffer + ring_index, buff, d * 4);	else	{	    int32 *p;	    int n;	    p = ring_buffer + ring_index;	    n = d * 2;	    for(i = 0; i < n; i += 2)		*p++ = (buff[i] + buff[i + 1]) / 2;	}	ring_index = 0;	outcnt += d;	samples -= d;    }    if(play_mode->encoding & PE_MONO)	memcpy(ring_buffer + ring_index, buff, samples * 4);    else    {	int32 *p;	int n;	p = ring_buffer + ring_index;	n = samples * 2;	for(i = 0; i < n; i += 2)	    *p++ = (buff[i] + buff[i + 1]) / 2;    }    ring_index += samples;    outcnt += samples;    if(ring_index == ring_buffer_len)	ring_index = 0;    if(next_wakeup_samples < outcnt - (ring_buffer_len - FFTSIZE))    {	/* next_wakeup_samples is too small */	next_wakeup_samples = outcnt - (ring_buffer_len - FFTSIZE);    }    while(next_wakeup_samples < outcnt - FFTSIZE)    {	double x[FFTSIZE];	struct drawing_queue *q;	ringsamples(x, next_wakeup_samples % ring_buffer_len, FFTSIZE);	q = new_queue();	decibelspec(x, q->values);	push_midi_time_vp(midi_trace.offset + next_wakeup_samples,			  trace_draw_scope,			  q);	next_wakeup_samples += soundspec_update_interval;    }}/* Re-initialize something */void soundspec_reinit(void){    initialize_exp_hz_table(soundspec_zoom);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -