annotate src/ext/kissfft/tools/psdpng.c @ 196:da283326bcd3 tip master

Update plugin versions in RDF
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 28 Feb 2020 09:43:02 +0000
parents 5ed6e970541b
children
rev   line source
c@174 1 /*
c@174 2 Copyright (c) 2003-2004, Mark Borgerding
c@174 3
c@174 4 All rights reserved.
c@174 5
c@174 6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
c@174 7
c@174 8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
c@174 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.
c@174 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.
c@174 11
c@174 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.
c@174 13 */
c@174 14
c@174 15 #include <stdlib.h>
c@174 16 #include <math.h>
c@174 17 #include <stdio.h>
c@174 18 #include <string.h>
c@174 19 #include <unistd.h>
c@174 20 #include <png.h>
c@174 21
c@174 22 #include "kiss_fft.h"
c@174 23 #include "kiss_fftr.h"
c@174 24
c@174 25 int nfft=1024;
c@174 26 FILE * fin=NULL;
c@174 27 FILE * fout=NULL;
c@174 28
c@174 29 int navg=20;
c@174 30 int remove_dc=0;
c@174 31 int nrows=0;
c@174 32 float * vals=NULL;
c@174 33 int stereo=0;
c@174 34
c@174 35 static
c@174 36 void config(int argc,char** argv)
c@174 37 {
c@174 38 while (1) {
c@174 39 int c = getopt (argc, argv, "n:r:as");
c@174 40 if (c == -1)
c@174 41 break;
c@174 42 switch (c) {
c@174 43 case 'n': nfft=(int)atoi(optarg);break;
c@174 44 case 'r': navg=(int)atoi(optarg);break;
c@174 45 case 'a': remove_dc=1;break;
c@174 46 case 's': stereo=1;break;
c@174 47 case '?':
c@174 48 fprintf (stderr, "usage options:\n"
c@174 49 "\t-n d: fft dimension(s) [1024]\n"
c@174 50 "\t-r d: number of rows to average [20]\n"
c@174 51 "\t-a : remove average from each fft buffer\n"
c@174 52 "\t-s : input is stereo, channels will be combined before fft\n"
c@174 53 "16 bit machine format real input is assumed\n"
c@174 54 );
c@174 55 default:
c@174 56 fprintf (stderr, "bad %c\n", c);
c@174 57 exit (1);
c@174 58 break;
c@174 59 }
c@174 60 }
c@174 61 if ( optind < argc ) {
c@174 62 if (strcmp("-",argv[optind]) !=0)
c@174 63 fin = fopen(argv[optind],"rb");
c@174 64 ++optind;
c@174 65 }
c@174 66
c@174 67 if ( optind < argc ) {
c@174 68 if ( strcmp("-",argv[optind]) !=0 )
c@174 69 fout = fopen(argv[optind],"wb");
c@174 70 ++optind;
c@174 71 }
c@174 72 if (fin==NULL)
c@174 73 fin=stdin;
c@174 74 if (fout==NULL)
c@174 75 fout=stdout;
c@174 76 }
c@174 77
c@174 78 #define CHECKNULL(p) if ( (p)==NULL ) do { fprintf(stderr,"CHECKNULL failed @ %s(%d): %s\n",__FILE__,__LINE__,#p );exit(1);} while(0)
c@174 79
c@174 80 typedef struct
c@174 81 {
c@174 82 png_byte r;
c@174 83 png_byte g;
c@174 84 png_byte b;
c@174 85 } rgb_t;
c@174 86
c@174 87 static
c@174 88 void val2rgb(float x,rgb_t *p)
c@174 89 {
c@174 90 const double pi = 3.14159265358979;
c@174 91 p->g = (int)(255*sin(x*pi));
c@174 92 p->r = (int)(255*abs(sin(x*pi*3/2)));
c@174 93 p->b = (int)(255*abs(sin(x*pi*5/2)));
c@174 94 //fprintf(stderr,"%.2f : %d,%d,%d\n",x,(int)p->r,(int)p->g,(int)p->b);
c@174 95 }
c@174 96
c@174 97 static
c@174 98 void cpx2pixels(rgb_t * res,const float * fbuf,size_t n)
c@174 99 {
c@174 100 size_t i;
c@174 101 float minval,maxval,valrange;
c@174 102 minval=maxval=fbuf[0];
c@174 103
c@174 104 for (i = 0; i < n; ++i) {
c@174 105 if (fbuf[i] > maxval) maxval = fbuf[i];
c@174 106 if (fbuf[i] < minval) minval = fbuf[i];
c@174 107 }
c@174 108
c@174 109 fprintf(stderr,"min ==%f,max=%f\n",minval,maxval);
c@174 110 valrange = maxval-minval;
c@174 111 if (valrange == 0) {
c@174 112 fprintf(stderr,"min == max == %f\n",minval);
c@174 113 exit (1);
c@174 114 }
c@174 115
c@174 116 for (i = 0; i < n; ++i)
c@174 117 val2rgb( (fbuf[i] - minval)/valrange , res+i );
c@174 118 }
c@174 119
c@174 120 static
c@174 121 void transform_signal(void)
c@174 122 {
c@174 123 short *inbuf;
c@174 124 kiss_fftr_cfg cfg=NULL;
c@174 125 kiss_fft_scalar *tbuf;
c@174 126 kiss_fft_cpx *fbuf;
c@174 127 float *mag2buf;
c@174 128 int i;
c@174 129 int n;
c@174 130 int avgctr=0;
c@174 131
c@174 132 int nfreqs=nfft/2+1;
c@174 133
c@174 134 CHECKNULL( cfg=kiss_fftr_alloc(nfft,0,0,0) );
c@174 135 CHECKNULL( inbuf=(short*)malloc(sizeof(short)*2*nfft ) );
c@174 136 CHECKNULL( tbuf=(kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar)*nfft ) );
c@174 137 CHECKNULL( fbuf=(kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx)*nfreqs ) );
c@174 138 CHECKNULL( mag2buf=(float*)malloc(sizeof(float)*nfreqs ) );
c@174 139
c@174 140 memset(mag2buf,0,sizeof(mag2buf)*nfreqs);
c@174 141
c@174 142 while (1) {
c@174 143 if (stereo) {
c@174 144 n = fread(inbuf,sizeof(short)*2,nfft,fin);
c@174 145 if (n != nfft )
c@174 146 break;
c@174 147 for (i=0;i<nfft;++i)
c@174 148 tbuf[i] = inbuf[2*i] + inbuf[2*i+1];
c@174 149 }else{
c@174 150 n = fread(inbuf,sizeof(short),nfft,fin);
c@174 151 if (n != nfft )
c@174 152 break;
c@174 153 for (i=0;i<nfft;++i)
c@174 154 tbuf[i] = inbuf[i];
c@174 155 }
c@174 156
c@174 157 if (remove_dc) {
c@174 158 float avg = 0;
c@174 159 for (i=0;i<nfft;++i) avg += tbuf[i];
c@174 160 avg /= nfft;
c@174 161 for (i=0;i<nfft;++i) tbuf[i] -= (kiss_fft_scalar)avg;
c@174 162 }
c@174 163
c@174 164 /* do FFT */
c@174 165 kiss_fftr(cfg,tbuf,fbuf);
c@174 166
c@174 167 for (i=0;i<nfreqs;++i)
c@174 168 mag2buf[i] += fbuf[i].r * fbuf[i].r + fbuf[i].i * fbuf[i].i;
c@174 169
c@174 170 if (++avgctr == navg) {
c@174 171 avgctr=0;
c@174 172 ++nrows;
c@174 173 vals = (float*)realloc(vals,sizeof(float)*nrows*nfreqs);
c@174 174 float eps = 1;
c@174 175 for (i=0;i<nfreqs;++i)
c@174 176 vals[(nrows - 1) * nfreqs + i] = 10 * log10 ( mag2buf[i] / navg + eps );
c@174 177 memset(mag2buf,0,sizeof(mag2buf[0])*nfreqs);
c@174 178 }
c@174 179 }
c@174 180
c@174 181 free(cfg);
c@174 182 free(inbuf);
c@174 183 free(tbuf);
c@174 184 free(fbuf);
c@174 185 free(mag2buf);
c@174 186 }
c@174 187
c@174 188 static
c@174 189 void make_png(void)
c@174 190 {
c@174 191 png_bytepp row_pointers=NULL;
c@174 192 rgb_t * row_data=NULL;
c@174 193 int i;
c@174 194 int nfreqs = nfft/2+1;
c@174 195
c@174 196 png_structp png_ptr=NULL;
c@174 197 png_infop info_ptr=NULL;
c@174 198
c@174 199 CHECKNULL( png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0) );
c@174 200 CHECKNULL( info_ptr = png_create_info_struct(png_ptr) );
c@174 201
c@174 202
c@174 203 png_init_io(png_ptr, fout );
c@174 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 );
c@174 205
c@174 206
c@174 207 row_data = (rgb_t*)malloc(sizeof(rgb_t) * nrows * nfreqs) ;
c@174 208 cpx2pixels(row_data, vals, nfreqs*nrows );
c@174 209
c@174 210 row_pointers = realloc(row_pointers, nrows*sizeof(png_bytep));
c@174 211 for (i=0;i<nrows;++i) {
c@174 212 row_pointers[i] = (png_bytep)(row_data + i*nfreqs);
c@174 213 }
c@174 214 png_set_rows(png_ptr, info_ptr, row_pointers);
c@174 215
c@174 216
c@174 217 fprintf(stderr,"creating %dx%d png\n",nfreqs,nrows);
c@174 218 fprintf(stderr,"bitdepth %d \n",png_get_bit_depth(png_ptr,info_ptr ) );
c@174 219
c@174 220 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY , NULL);
c@174 221
c@174 222 }
c@174 223
c@174 224 int main(int argc,char ** argv)
c@174 225 {
c@174 226 config(argc,argv);
c@174 227
c@174 228 transform_signal();
c@174 229
c@174 230 make_png();
c@174 231
c@174 232 if (fout!=stdout) fclose(fout);
c@174 233 if (fin!=stdin) fclose(fin);
c@174 234 return 0;
c@174 235 }