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

📄 soundspec.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    This program 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 of the License, or    (at your option) any later version.    This program 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 this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/keysym.h>#include <X11/Xatom.h>#include <math.h>#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#define DEBUG 1#include "timidity.h"#include "common.h"#include "instrum.h"#include "playmidi.h"#include "output.h"#include "controls.h"#include "soundspec.h"#include "fft.h"#include "miditrace.h"#define FFTSIZE 1024		/* Power of 2 */#define SCOPE_HEIGHT 512	/* You can specified any positive value */#define SCOPE_WIDTH  512	/* You can specified any positive value */#define SCROLL_THRESHOLD 256	/* 1 <= SCROLL_THRESHOLD <= SCOPE_WIDTH */#define NCOLOR    64		/* 1 <= NCOLOR <= 255 */#define AMP 1.0#define AMP2 1.5#define DEFAULT_ZOOM (44100.0/1024.0*2.0) /* ~86Hz */#define MIN_ZOOM 15.0	/* 15Hz is the lowest bound that human can be heard. */#define MAX_ZOOM 440.0#define DEFAULT_UPDATE 0.05static int32 *ring_buffer = NULL;#define ring_buffer_len (8 * AUDIO_BUFFER_SIZE)static int ring_index;static int32 outcnt;static double exp_hz_table[SCOPE_HEIGHT+1];int view_soundspec_flag = 0;int ctl_speana_flag = 0;int32 soundspec_update_interval = 0;static int32 next_wakeup_samples;static double soundspec_zoom = DEFAULT_ZOOM;static Display *disp = NULL;static Window win;static GC gc;static int depth;static Pixmap offscr;static XImage *img;static Atom wm_delete_window;static unsigned long color_ring[NCOLOR];#define XCMAP(disp) XDefaultColormap(disp, DefaultScreen(disp))typedef struct _rgb_t {    double r, g, b;} rgb_t;static void hsv_to_rgb(double h, double s, double v, rgb_t *rgb){    double f;    double i;    double p1, p2, p3;    if (s < 0)	s = 0;    if (v < 0)	v = 0;    if (s > 1)	s = 1;    if (v > 1)	v = 1;    h = fmod(h, 360.0);    if (h < 0)	h += 360;    h /= 60;    f = modf(h, &i);    p1 = v * (1 - s);    p2 = v * (1 - s * f);    p3 = v * (1 - s * (1 - f));    switch ((int)i) {      case 0:	rgb->r = v;	rgb->g = p3;	rgb->b = p1;	return;      case 1:	rgb->r = p2;	rgb->g = v;	rgb->b = p1;	return;      case 2:	rgb->r = p1;	rgb->g = v;	rgb->b = p3;	return;      case 3:	rgb->r = p1;	rgb->g = p2;	rgb->b = v;	return;      case 4:	rgb->r = p3;	rgb->g = p1;	rgb->b = v;	return;      case 5:	rgb->r = v;	rgb->g = p1;	rgb->b = p2;	return;    }    return;}static double calc_color_diff(int r1, int g1, int b1,			      int r2, int g2, int b2){    double rd, gd, bd;    rd = r2 - r1;    gd = g2 - g1;    bd = b2 - b1;    return rd * rd + gd * gd + bd * bd;}static long search_near_color(Display *disp, int r, int g, int b){    double d, mind;    int scr;    static XColor *xc = NULL;    static int xc_size = 0;    long i, k;    scr = DefaultScreen(disp);    if(depth == 1)		/* black or white */    {	d = (double)r * r	  + (double)g * g	  + (double)b * b;	if(d > 3.0 * 32768.0 * 32768.0)	    return (long)WhitePixel(disp, scr);	return (long)BlackPixel(disp, scr);    }    if(xc_size == 0)    {	xc_size = DisplayCells(disp, scr);	if(xc_size > 256)	    return 0; /* Colormap size is too large */	xc = (XColor *)safe_malloc(sizeof(XColor) * xc_size);	for(i = 0; i < xc_size; i++)	    xc[i].pixel = i;    }    XQueryColors(disp, DefaultColormap(disp, scr), xc, xc_size);    mind = calc_color_diff(r, g, b, xc[0].red, xc[0].green, xc[0].blue);    k = 0;    for(i = 1; i < xc_size; i++)    {	d = calc_color_diff(r, g, b, xc[i].red, xc[i].green, xc[i].blue);	if(d < mind)	{	    mind = d;	    k = i;	    if(mind == 0.0)		break;	}    }#ifdef DEBUG    printf("color [%04x %04x %04x]->[%04x %04x %04x] (d^2=%f, k=%d)\n",	   r, g, b,	   xc[k].red, xc[k].green, xc[k].blue,	   mind, (int)k);#endif    return k;}#if 0static int highbit(unsigned long ul){    int i;  unsigned long hb;    hb = 0x80000000UL;    for(i = 31; ((ul & hb) == 0) && i >= 0;  i--, ul<<=1)	;    return i;}#endifstatic unsigned long AllocRGBColor(	Display *disp,	double red,		/* [0, 1] */	double green,		/* [0, 1] */	double blue)		/* [0, 1] */{    XColor c;    c.red = (unsigned short)(red * 0xffff);    c.green = (unsigned short)(green * 0xffff);    c.blue = (unsigned short)(blue * 0xffff);    if(!XAllocColor(disp, XCMAP(disp), &c))    {	ctl->cmsg(CMSG_INFO, VERB_NOISY,		  "Warning: Can't allocate color: "		  "r = %04x, g = %04x, b = %04x", c.red, c.green, c.blue);	return search_near_color(disp, c.red, c.green, c.blue);    }    return c.pixel;}static void set_color_ring(void){    int i;    /*i = 0          ...        NCOLOR     *  Blue -> Green -> Red -> White     */    for(i = 0; i < NCOLOR; i++)    {	rgb_t rgb;	double h = 240 - 360 * sqrt((1.0/NCOLOR) * i);	double s, v;	if(h >= 0)	    s = 0.9;	else	{	    s = 0.9 + h / 120.0 * 0.9;	    h = 0.0;	}/*	v = sqrt(i * (1.0/NCOLOR) * 0.6 + 0.4); */	v = 1.0;	hsv_to_rgb(h, s, v, &rgb);	color_ring[i] = AllocRGBColor(disp, rgb.r, rgb.g, rgb.b);    }}static void set_draw_pixel(double *val, char *pixels){    int i;    unsigned v;    for(i = 0; i < SCOPE_HEIGHT; i++)    {	v = (unsigned)(val[i] * AMP2);	if(v > NCOLOR - 1)	    val[i] = NCOLOR - 1;	else	    val[i] = v;    }    switch(depth) {      case 32:      case 24:	for(i = 0; i < SCOPE_HEIGHT; i++)	    ((uint32 *)pixels)[i] = (uint32)color_ring[(int)val[SCOPE_HEIGHT - i - 1]];	break;      case 16:	for(i = 0; i < SCOPE_HEIGHT; i++)	    ((uint16 *)pixels)[i] = (uint16)color_ring[(int)val[SCOPE_HEIGHT - i - 1]];	break;      default:	for(i = 0; i < SCOPE_HEIGHT; i++)	    ((uint8 *)pixels)[i] = (uint8)color_ring[(int)val[SCOPE_HEIGHT - i - 1]];	break;    }}static void make_logspectrogram(double *from, double *to){    double px;    int i;    to[0] = from[0];    px = 0.0;    for(i = 1; i < SCOPE_HEIGHT - 1; i++)    {        double tx, s;        int x1, n;        tx = exp_hz_table[i];        x1 = (int)px;        n = 0;        s = 0.0;        do        {	    double a;            a = from[x1];            s += a + (tx - x1) * (from[x1 + 1] - a);            n++;            x1++;        } while(x1 < tx);        to[i] = s / n;        px = tx;    }    to[SCOPE_HEIGHT - 1] = from[FFTSIZE / 2 - 1];    for(i = 0; i < SCOPE_HEIGHT; i++)	if(to[i] <= -0.0)	    to[i] = 0.0;}static void initialize_exp_hz_table(double zoom){    int i;    double r, x, w;    if(zoom < MIN_ZOOM)	soundspec_zoom = MIN_ZOOM;    else if(zoom > MAX_ZOOM)	soundspec_zoom = MAX_ZOOM;    else	soundspec_zoom = zoom;    w = (double)play_mode->rate * 0.5 / zoom;    r = exp(log(w) * (1.0/SCOPE_HEIGHT));    w = (FFTSIZE/2.0) / (w - 1.0);    for(i = 0, x = 1.0; i <= SCOPE_HEIGHT; i++, x *= r)	exp_hz_table[i] = (x - 1.0) * w;}static KeySym xlookup_key(XKeyEvent *e){    char str[10];    KeySym key;    XLookupString(e, str, 10, &key, NULL);    return key;}static void draw_scope(double *values){    static int32 call_cnt;    int offset, expose;    XEvent e;    char pixels[SCOPE_HEIGHT*32];    double work[SCOPE_HEIGHT];    int nze;    char *mname;    KeySym k;

⌨️ 快捷键说明

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