0

I am trying to compute a spectrogram in C++. I am doing the Short Time Fourier Transform (STFT) using a Hann window and am following this example, and I get an array of complex values from the transform. However I am not sure how to go about plotting the data (I am using gnuplot).

I've read to get the magnitude, i need to take the L2 norm:
sqrt(real^2 + imag^2)

and to get the Frequency at a location in the array we do
index * sampleFrequency / windowSize.
Source: Converting an FFT to a spectogram

I was plotting time vs frequency (with magnitude to be added later as the heatmap color), but the results look strange:

enter image description here
Edit: Here is the first 0.01th of a second of the STFT'd sound, where the first column is time (which is computed by dividing index by the sample frequency, 32k in this case), and second column is frequency (computation above):

0.00000 0.00
0.00003 15.00
0.00006 31.00
0.00009 46.00
0.00013 62.00
0.00016 78.00
0.00019 93.00
0.00022 109.00
0.00025 125.00
0.00028 140.00
0.00031 156.00
0.00034 171.00
0.00038 187.00
0.00041 203.00
0.00044 218.00
0.00047 234.00
0.00050 250.00
0.00053 265.00
0.00056 281.00
0.00059 296.00
0.00062 312.00
0.00066 328.00
0.00069 343.00
0.00072 359.00
0.00075 375.00
0.00078 390.00
0.00081 406.00
0.00084 421.00
0.00088 437.00
0.00091 453.00
0.00094 468.00
0.00097 484.00
0.00100 500.00
0.00103 515.00
0.00106 531.00
0.00109 546.00
0.00112 562.00
0.00116 578.00
0.00119 593.00
0.00122 609.00
0.00125 625.00
0.00128 640.00
0.00131 656.00
0.00134 671.00
0.00137 687.00
0.00141 703.00
0.00144 718.00
0.00147 734.00
0.00150 750.00
0.00153 765.00
0.00156 781.00
0.00159 796.00
0.00163 812.00
0.00166 828.00
0.00169 843.00
0.00172 859.00
0.00175 875.00
0.00178 890.00
0.00181 906.00
0.00184 921.00
0.00187 937.00
0.00191 953.00
0.00194 968.00
0.00197 984.00
0.00200 1000.00
0.00203 1015.00
0.00206 1031.00
0.00209 1046.00
0.00213 1062.00
0.00216 1078.00
0.00219 1093.00
0.00222 1109.00
0.00225 1125.00
0.00228 1140.00
0.00231 1156.00
0.00234 1171.00
0.00237 1187.00
0.00241 1203.00
0.00244 1218.00
0.00247 1234.00
0.00250 1250.00
0.00253 1265.00
0.00256 1281.00
0.00259 1296.00
0.00262 1312.00
0.00266 1328.00
0.00269 1343.00
0.00272 1359.00
0.00275 1375.00
0.00278 1390.00
0.00281 1406.00
0.00284 1421.00
0.00288 1437.00
0.00291 1453.00
0.00294 1468.00
0.00297 1484.00
0.00300 1500.00
0.00303 1515.00
0.00306 1531.00
0.00309 1546.00
0.00313 1562.00
0.00316 1578.00
0.00319 1593.00
0.00322 1609.00
0.00325 1625.00
0.00328 1640.00
0.00331 1656.00
0.00334 1671.00
0.00338 1687.00
0.00341 1703.00
0.00344 1718.00
0.00347 1734.00
0.00350 1750.00
0.00353 1765.00
0.00356 1781.00
0.00359 1796.00
0.00362 1812.00
0.00366 1828.00
0.00369 1843.00
0.00372 1859.00
0.00375 1875.00
0.00378 1890.00
0.00381 1906.00
0.00384 1921.00
0.00387 1937.00
0.00391 1953.00
0.00394 1968.00
0.00397 1984.00
0.00400 2000.00
0.00403 2015.00
0.00406 2031.00
0.00409 2046.00
0.00412 2062.00
0.00416 2078.00
0.00419 2093.00
0.00422 2109.00
0.00425 2125.00
0.00428 2140.00
0.00431 2156.00
0.00434 2171.00
0.00438 2187.00
0.00441 2203.00
0.00444 2218.00
0.00447 2234.00
0.00450 2250.00
0.00453 2265.00
0.00456 2281.00
0.00459 2296.00
0.00463 2312.00
0.00466 2328.00
0.00469 2343.00
0.00472 2359.00
0.00475 2375.00
0.00478 2390.00
0.00481 2406.00
0.00484 2421.00
0.00488 2437.00
0.00491 2453.00
0.00494 2468.00
0.00497 2484.00
0.00500 2500.00
0.00503 2515.00
0.00506 2531.00
0.00509 2546.00
0.00513 2562.00
0.00516 2578.00
0.00519 2593.00
0.00522 2609.00
0.00525 2625.00
0.00528 2640.00
0.00531 2656.00
0.00534 2671.00
0.00538 2687.00
0.00541 2703.00
0.00544 2718.00
0.00547 2734.00
0.00550 2750.00
0.00553 2765.00
0.00556 2781.00
0.00559 2796.00
0.00563 2812.00
0.00566 2828.00
0.00569 2843.00
0.00572 2859.00
0.00575 2875.00
0.00578 2890.00
0.00581 2906.00
0.00584 2921.00
0.00587 2937.00
0.00591 2953.00
0.00594 2968.00
0.00597 2984.00
0.00600 3000.00
0.00603 3015.00
0.00606 3031.00
0.00609 3046.00
0.00612 3062.00
0.00616 3078.00
0.00619 3093.00
0.00622 3109.00
0.00625 3125.00
0.00628 3140.00
0.00631 3156.00
0.00634 3171.00
0.00637 3187.00
0.00641 3203.00
0.00644 3218.00
0.00647 3234.00
0.00650 3250.00
0.00653 3265.00
0.00656 3281.00
0.00659 3296.00
0.00662 3312.00
0.00666 3328.00
0.00669 3343.00
0.00672 3359.00
0.00675 3375.00
0.00678 3390.00
0.00681 3406.00
0.00684 3421.00
0.00687 3437.00
0.00691 3453.00
0.00694 3468.00
0.00697 3484.00
0.00700 3500.00
0.00703 3515.00
0.00706 3531.00
0.00709 3546.00
0.00713 3562.00
0.00716 3578.00
0.00719 3593.00
0.00722 3609.00
0.00725 3625.00
0.00728 3640.00
0.00731 3656.00
0.00734 3671.00
0.00738 3687.00
0.00741 3703.00
0.00744 3718.00
0.00747 3734.00
0.00750 3750.00
0.00753 3765.00
0.00756 3781.00
0.00759 3796.00
0.00763 3812.00
0.00766 3828.00
0.00769 3843.00
0.00772 3859.00
0.00775 3875.00
0.00778 3890.00
0.00781 3906.00
0.00784 3921.00
0.00788 3937.00
0.00791 3953.00
0.00794 3968.00
0.00797 3984.00
0.00800 4000.00
0.00803 4015.00
0.00806 4031.00
0.00809 4046.00
0.00812 4062.00
0.00816 4078.00
0.00819 4093.00
0.00822 4109.00
0.00825 4125.00
0.00828 4140.00
0.00831 4156.00
0.00834 4171.00
0.00838 4187.00
0.00841 4203.00
0.00844 4218.00
0.00847 4234.00
0.00850 4250.00
0.00853 4265.00
0.00856 4281.00
0.00859 4296.00
0.00862 4312.00
0.00866 4328.00
0.00869 4343.00
0.00872 4359.00
0.00875 4375.00
0.00878 4390.00
0.00881 4406.00
0.00884 4421.00
0.00888 4437.00
0.00891 4453.00
0.00894 4468.00
0.00897 4484.00
0.00900 4500.00
0.00903 4515.00
0.00906 4531.00
0.00909 4546.00
0.00912 4562.00
0.00916 4578.00
0.00919 4593.00
0.00922 4609.00
0.00925 4625.00
0.00928 4640.00
0.00931 4656.00
0.00934 4671.00
0.00938 4687.00
0.00941 4703.00
0.00944 4718.00
0.00947 4734.00
0.00950 4750.00
0.00953 4765.00
0.00956 4781.00
0.00959 4796.00
0.00962 4812.00
0.00966 4828.00
0.00969 4843.00
0.00972 4859.00
0.00975 4875.00
0.00978 4890.00
0.00981 4906.00
0.00984 4921.00
0.00988 4937.00
0.00991 4953.00
0.00994 4968.00
0.00997 4984.00
0.01000 5000.00

Is my approach correct for plotting plotting frequency on y axis, time on x axis, and magnitude on "z-axis" (using color spectrum) to make a spectrogram?

  • you show the gnuplot graph, but no example data and no gnuplot code. Please edit the question and add more information. With this it would be easier to get help. – theozh Jul 28 '20 at 04:31
  • My data file is absolutely massive, so I didnt attach it. My question is about the concept rather than gnuplot specifics; I just ran plot 'datafileName.txt'. Do I have the approach correct by plotting time (x axis) vs frequency (y axis), with z axis (magnitude) to be added later as heatmap for spectrogram? – mrwhynot243 Jul 28 '20 at 15:02
  • `plot 'datafileName.txt'` will plot the first column vs. the second column of your datafile with points. That's apparently what you got. Without knowing how the structure of the datafile looks like it's difficult to propose any gnuplot code. A few example lines would be enough. – theozh Jul 28 '20 at 15:27
  • I edited the above to include the first hundreth of a second of the sample data. – mrwhynot243 Jul 28 '20 at 16:58
  • ok, and where is magnitude? – theozh Jul 28 '20 at 17:18
  • I did not add magnitude yet, as I was trying to get the 2d plot set correctly before using the 3rd dimension (magnitude) for heatmap. Does it just boil down to plotting time (x axis), frequency (y axis), magnitude (z axis heatmap)? – mrwhynot243 Jul 28 '20 at 17:40
  • check out e.g. this http://gnuplot.sourceforge.net/demo_5.2/heatmaps.html I would guess your data should have the format with blocks where rows are separated by blank lines (Second example there). – theozh Jul 28 '20 at 17:45

0 Answers0