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

📄 fft.cpp

📁 一个KDE下的录音程序
💻 CPP
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <math.h>#include <qwidget.h>#include "sound.h"#include "fft.moc"#include <X11/Xlib.h>extern "C" {  #include "soundfft.h"}#define FFT_MAX     8192#define FFT_LEFT     100#define FFT_RIGHT  10000#define DB_MAX       0.0#define DB_MIN    -100.0/* ---------------------------------------------------------------------- */FFTWindow::FFTWindow(QWidget *parent, char *name) : QWidget(parent,name,0){    XColor color,dummy;    Colormap map = DefaultColormapOfScreen	(DefaultScreenOfDisplay(x11Display()));        gc = XCreateGC(x11Display(),winId(),0,NULL);    XAllocNamedColor(x11Display(),map,"white",&color,&dummy);    back = color.pixel;    XAllocNamedColor(x11Display(),map,"red",&color,&dummy);    fore = color.pixel;    /* flag: no init so far... */    channels = 0;    logmap = NULL;    ylog = false;}voidFFTWindow::make_logmap(){    int   i,w,h;    float freq,up;    w = width();    h = height();    if (!w || !h || !channels)	return;        if (logmap) {        free(logmap);        free(segments);	free(buffer);	EndFFT();    }    logmap   = (int*) malloc((w+1)*sizeof(int));    segments = (XSegment*)malloc((w)*sizeof(XSegment));    buffer   = (short*)malloc(fft_size*sizeof(short)*channels);    InitializeFFT(fft_size);    up = log(FFT_RIGHT/FFT_LEFT)/log(2);    for (i = 0; i <= w; i++) {        freq = pow(2,up*i/w)* FFT_LEFT;	logmap[i] = (int)(fft_size*freq/rate);    }    for (i = 0; i < w; i++) {        segments[i].x1 = i;        segments[i].x2 = i;        segments[i].y2 = h;    }}voidFFTWindow::calculate(unsigned char *data){    int i,j;    if (NULL == logmap) {	fprintf(stderr,"Oops: fft no logmap (yet)\n");	return;    }    switch (afmt) {    case FMT_8BIT:        for (i = 0; i < audio_size; i++)            buffer[i] = (data[i] ^ 0x80) << 8;        break;#if 0    case AFMT_S8:        for (i = 0; i < audio_size; i++)            buffer[i] = data[i] << 8;        break;#endif    case FMT_16BIT:        memcpy(buffer,data,audio_size);#if 0	/* byte swap */	for (i = 0; i < fft_size; i++)	    buffer[i] =		((buffer[i] & 0xff00) >> 8) |		((buffer[i] & 0x00ff) << 8);	/* unsigned -> signed */        if (afmt == AFMT_U16_LE || afmt == AFMT_U16_BE)            for (i = 0; i < fft_size; i++)                buffer[i] ^= 0x8000;#endif        break;    default:        fprintf(stderr,"oops(fft): unknown sound format\n");        exit(1);    }    for (i = 0, lmax = 0; i < fft_size; i++)        if ((j = abs((signed short)buffer[i])) > lmax)            lmax = j;    if (channels == 2) {        for (i = 0, j = 0; i < fft_size; i++, j+=2)            buffer[i] = (buffer[j]+buffer[j+1])>>1;    }    RealFFT(buffer);}voidFFTWindow::drawhist(){    XGCValues gcval;    int re,im,ab;    int i,j,max,w,h;    int len = fft_size>>1;    w = width();    h = height();    for (i = 0; i < w; i++) {        max = 0;        j = logmap[i];        do {            if (j >= len)                break;            re = buffer[BitReversed[j]];            im = buffer[BitReversed[j]+1];            ab = re*re+im*im;            if (ab > max)                max = ab;            j++;        } while (j < logmap[i+1]);        if (ylog) {            float dBVal = 20 * log10( sqrt(max)/FFT_MAX );            max = (int)( h * ( dBVal-DB_MIN )/( DB_MAX-DB_MIN ));        } else {            max = (int)(sqrt(max) * h / FFT_MAX);        }        segments[i].y1 = h-max;    }    gcval.foreground = back;    XChangeGC(x11Display(),gc,GCForeground,&gcval);    XFillRectangle(x11Display(),winId(),gc,0,0,width(),height());    gcval.foreground = fore;    XChangeGC(x11Display(),gc,GCForeground,&gcval);    XDrawSegments(x11Display(),winId(),gc,segments,w);    if (ylog) {	float dBVal = 20 * log10( (double)lmax/32768 );	max = h - (int)( h * ( dBVal-DB_MIN )/( DB_MAX-DB_MIN ));    } else {	max = height() - lmax*height()/32768;    }    XDrawLine(x11Display(),winId(),gc,0,max,width(),max);}/* ---------------------------------------------------------------------- */voidFFTWindow::resizeEvent(QResizeEvent *event){    make_logmap();}voidFFTWindow::new_params(struct SOUNDPARAMS *p){    afmt        = p->format;    channels    = p->channels;    rate        = p->rate;    audio_size  = p->blocksize;    fft_size = audio_size/channels/2;    if (afmt != FMT_16BIT)        fft_size *= 2;    make_logmap();}voidFFTWindow::new_data(void *data){    if (!channels || !isVisible())	return;        calculate((unsigned char*)data);    drawhist();}voidFFTWindow::set_ylog(int linear){    ylog = (linear==0);    drawhist();}

⌨️ 快捷键说明

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