annotate constant-q-cpp/src/ext/kissfft/tools/psdpng.c @ 372:af71cbdab621 tip

Update bqvec code
author Chris Cannam
date Tue, 19 Nov 2019 10:13:32 +0000
parents 5d0a2ebb4d17
children
rev   line source
Chris@366 1 /*
Chris@366 2 Copyright (c) 2003-2004, Mark Borgerding
Chris@366 3
Chris@366 4 All rights reserved.
Chris@366 5
Chris@366 6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Chris@366 7
Chris@366 8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Chris@366 9 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Chris@366 10 * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
Chris@366 11
Chris@366 12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@366 13 */
Chris@366 14
Chris@366 15 #include <stdlib.h>
Chris@366 16 #include <math.h>
Chris@366 17 #include <stdio.h>
Chris@366 18 #include <string.h>
Chris@366 19 #include <unistd.h>
Chris@366 20 #include <png.h>
Chris@366 21
Chris@366 22 #include "kiss_fft.h"
Chris@366 23 #include "kiss_fftr.h"
Chris@366 24
Chris@366 25 int nfft=1024;
Chris@366 26 FILE * fin=NULL;
Chris@366 27 FILE * fout=NULL;
Chris@366 28
Chris@366 29 int navg=20;
Chris@366 30 int remove_dc=0;
Chris@366 31 int nrows=0;
Chris@366 32 float * vals=NULL;
Chris@366 33 int stereo=0;
Chris@366 34
Chris@366 35 static
Chris@366 36 void config(int argc,char** argv)
Chris@366 37 {
Chris@366 38 while (1) {
Chris@366 39 int c = getopt (argc, argv, "n:r:as");
Chris@366 40 if (c == -1)
Chris@366 41 break;
Chris@366 42 switch (c) {
Chris@366 43 case 'n': nfft=(int)atoi(optarg);break;
Chris@366 44 case 'r': navg=(int)atoi(optarg);break;
Chris@366 45 case 'a': remove_dc=1;break;
Chris@366 46 case 's': stereo=1;break;
Chris@366 47 case '?':
Chris@366 48 fprintf (stderr, "usage options:\n"
Chris@366 49 "\t-n d: fft dimension(s) [1024]\n"
Chris@366 50 "\t-r d: number of rows to average [20]\n"
Chris@366 51 "\t-a : remove average from each fft buffer\n"
Chris@366 52 "\t-s : input is stereo, channels will be combined before fft\n"
Chris@366 53 "16 bit machine format real input is assumed\n"
Chris@366 54 );
Chris@366 55 default:
Chris@366 56 fprintf (stderr, "bad %c\n", c);
Chris@366 57 exit (1);
Chris@366 58 break;
Chris@366 59 }
Chris@366 60 }
Chris@366 61 if ( optind < argc ) {
Chris@366 62 if (strcmp("-",argv[optind]) !=0)
Chris@366 63 fin = fopen(argv[optind],"rb");
Chris@366 64 ++optind;
Chris@366 65 }
Chris@366 66
Chris@366 67 if ( optind < argc ) {
Chris@366 68 if ( strcmp("-",argv[optind]) !=0 )
Chris@366 69 fout = fopen(argv[optind],"wb");
Chris@366 70 ++optind;
Chris@366 71 }
Chris@366 72 if (fin==NULL)
Chris@366 73 fin=stdin;
Chris@366 74 if (fout==NULL)
Chris@366 75 fout=stdout;
Chris@366 76 }
Chris@366 77
Chris@366 78 #define CHECKNULL(p) if ( (p)==NULL ) do { fprintf(stderr,"CHECKNULL failed @ %s(%d): %s\n",__FILE__,__LINE__,#p );exit(1);} while(0)
Chris@366 79
Chris@366 80 typedef struct
Chris@366 81 {
Chris@366 82 png_byte r;
Chris@366 83 png_byte g;
Chris@366 84 png_byte b;
Chris@366 85 } rgb_t;
Chris@366 86
Chris@366 87 static
Chris@366 88 void val2rgb(float x,rgb_t *p)
Chris@366 89 {
Chris@366 90 const double pi = 3.14159265358979;
Chris@366 91 p->g = (int)(255*sin(x*pi));
Chris@366 92 p->r = (int)(255*abs(sin(x*pi*3/2)));
Chris@366 93 p->b = (int)(255*abs(sin(x*pi*5/2)));
Chris@366 94 //fprintf(stderr,"%.2f : %d,%d,%d\n",x,(int)p->r,(int)p->g,(int)p->b);
Chris@366 95 }
Chris@366 96
Chris@366 97 static
Chris@366 98 void cpx2pixels(rgb_t * res,const float * fbuf,size_t n)
Chris@366 99 {
Chris@366 100 size_t i;
Chris@366 101 float minval,maxval,valrange;
Chris@366 102 minval=maxval=fbuf[0];
Chris@366 103
Chris@366 104 for (i = 0; i < n; ++i) {
Chris@366 105 if (fbuf[i] > maxval) maxval = fbuf[i];
Chris@366 106 if (fbuf[i] < minval) minval = fbuf[i];
Chris@366 107 }
Chris@366 108
Chris@366 109 fprintf(stderr,"min ==%f,max=%f\n",minval,maxval);
Chris@366 110 valrange = maxval-minval;
Chris@366 111 if (valrange == 0) {
Chris@366 112 fprintf(stderr,"min == max == %f\n",minval);
Chris@366 113 exit (1);
Chris@366 114 }
Chris@366 115
Chris@366 116 for (i = 0; i < n; ++i)
Chris@366 117 val2rgb( (fbuf[i] - minval)/valrange , res+i );
Chris@366 118 }
Chris@366 119
Chris@366 120 static
Chris@366 121 void transform_signal(void)
Chris@366 122 {
Chris@366 123 short *inbuf;
Chris@366 124 kiss_fftr_cfg cfg=NULL;
Chris@366 125 kiss_fft_scalar *tbuf;
Chris@366 126 kiss_fft_cpx *fbuf;
Chris@366 127 float *mag2buf;
Chris@366 128 int i;
Chris@366 129 int n;
Chris@366 130 int avgctr=0;
Chris@366 131
Chris@366 132 int nfreqs=nfft/2+1;
Chris@366 133
Chris@366 134 CHECKNULL( cfg=kiss_fftr_alloc(nfft,0,0,0) );
Chris@366 135 CHECKNULL( inbuf=(short*)malloc(sizeof(short)*2*nfft ) );
Chris@366 136 CHECKNULL( tbuf=(kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar)*nfft ) );
Chris@366 137 CHECKNULL( fbuf=(kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx)*nfreqs ) );
Chris@366 138 CHECKNULL( mag2buf=(float*)malloc(sizeof(float)*nfreqs ) );
Chris@366 139
Chris@366 140 memset(mag2buf,0,sizeof(mag2buf)*nfreqs);
Chris@366 141
Chris@366 142 while (1) {
Chris@366 143 if (stereo) {
Chris@366 144 n = fread(inbuf,sizeof(short)*2,nfft,fin);
Chris@366 145 if (n != nfft )
Chris@366 146 break;
Chris@366 147 for (i=0;i<nfft;++i)
Chris@366 148 tbuf[i] = inbuf[2*i] + inbuf[2*i+1];
Chris@366 149 }else{
Chris@366 150 n = fread(inbuf,sizeof(short),nfft,fin);
Chris@366 151 if (n != nfft )
Chris@366 152 break;
Chris@366 153 for (i=0;i<nfft;++i)
Chris@366 154 tbuf[i] = inbuf[i];
Chris@366 155 }
Chris@366 156
Chris@366 157 if (remove_dc) {
Chris@366 158 float avg = 0;
Chris@366 159 for (i=0;i<nfft;++i) avg += tbuf[i];
Chris@366 160 avg /= nfft;
Chris@366 161 for (i=0;i<nfft;++i) tbuf[i] -= (kiss_fft_scalar)avg;
Chris@366 162 }
Chris@366 163
Chris@366 164 /* do FFT */
Chris@366 165 kiss_fftr(cfg,tbuf,fbuf);
Chris@366 166
Chris@366 167 for (i=0;i<nfreqs;++i)
Chris@366 168 mag2buf[i] += fbuf[i].r * fbuf[i].r + fbuf[i].i * fbuf[i].i;
Chris@366 169
Chris@366 170 if (++avgctr == navg) {
Chris@366 171 avgctr=0;
Chris@366 172 ++nrows;
Chris@366 173 vals = (float*)realloc(vals,sizeof(float)*nrows*nfreqs);
Chris@366 174 float eps = 1;
Chris@366 175 for (i=0;i<nfreqs;++i)
Chris@366 176 vals[(nrows - 1) * nfreqs + i] = 10 * log10 ( mag2buf[i] / navg + eps );
Chris@366 177 memset(mag2buf,0,sizeof(mag2buf[0])*nfreqs);
Chris@366 178 }
Chris@366 179 }
Chris@366 180
Chris@366 181 free(cfg);
Chris@366 182 free(inbuf);
Chris@366 183 free(tbuf);
Chris@366 184 free(fbuf);
Chris@366 185 free(mag2buf);
Chris@366 186 }
Chris@366 187
Chris@366 188 static
Chris@366 189 void make_png(void)
Chris@366 190 {
Chris@366 191 png_bytepp row_pointers=NULL;
Chris@366 192 rgb_t * row_data=NULL;
Chris@366 193 int i;
Chris@366 194 int nfreqs = nfft/2+1;
Chris@366 195
Chris@366 196 png_structp png_ptr=NULL;
Chris@366 197 png_infop info_ptr=NULL;
Chris@366 198
Chris@366 199 CHECKNULL( png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0) );
Chris@366 200 CHECKNULL( info_ptr = png_create_info_struct(png_ptr) );
Chris@366 201
Chris@366 202
Chris@366 203 png_init_io(png_ptr, fout );
Chris@366 204 png_set_IHDR(png_ptr, info_ptr ,nfreqs,nrows,8,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT );
Chris@366 205
Chris@366 206
Chris@366 207 row_data = (rgb_t*)malloc(sizeof(rgb_t) * nrows * nfreqs) ;
Chris@366 208 cpx2pixels(row_data, vals, nfreqs*nrows );
Chris@366 209
Chris@366 210 row_pointers = realloc(row_pointers, nrows*sizeof(png_bytep));
Chris@366 211 for (i=0;i<nrows;++i) {
Chris@366 212 row_pointers[i] = (png_bytep)(row_data + i*nfreqs);
Chris@366 213 }
Chris@366 214 png_set_rows(png_ptr, info_ptr, row_pointers);
Chris@366 215
Chris@366 216
Chris@366 217 fprintf(stderr,"creating %dx%d png\n",nfreqs,nrows);
Chris@366 218 fprintf(stderr,"bitdepth %d \n",png_get_bit_depth(png_ptr,info_ptr ) );
Chris@366 219
Chris@366 220 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY , NULL);
Chris@366 221
Chris@366 222 }
Chris@366 223
Chris@366 224 int main(int argc,char ** argv)
Chris@366 225 {
Chris@366 226 config(argc,argv);
Chris@366 227
Chris@366 228 transform_signal();
Chris@366 229
Chris@366 230 make_png();
Chris@366 231
Chris@366 232 if (fout!=stdout) fclose(fout);
Chris@366 233 if (fin!=stdin) fclose(fin);
Chris@366 234 return 0;
Chris@366 235 }