Open KinMaynard opened 3 years ago
New theory that speed issues are from the size of the data. It's probably calling a lot of draw for each data point and audio usually has around 44100 per second points. So chunking or using collections would help and might fix the problem.
Collections marginally helps but what needs to be done is chunking the data. I want to use a block-wise generator instead of an array of all the data for the display portions of this code. Since display doesn't require as much fidelity as playback I want to use a much smaller buffer size for the audio data. Displaying 44100 data points per second is unnecessary and impossible. It would be far more prudent to display a small power of 2 say 1024. I can use this small buffer for the display portions and use the full fidelity of the audio for playback/dsp. This error came from only understanding how necessary high fidelity is for playback and not realizing that it isn't necessary for visualization and in fact causes severe performance issues.
So where do I want to use blocks and where arrays? Use blocks for visualization functions & their tests and use arrays for dsp.
Adding block argument to visualization functions:
[ ] Waveform
[ ] Magnitude
[ ] Spectrogram
[ ] Vectorscope
[ ] Visualizer
[ ] Tests
Change 'data' argument to 'block'
Add Loop for block generator
Change docstring
Change Test arguments
Test
Accidental closing of issue. Reopened.
What do I want to accomplish using block processing instead of an array at 441khz/Sec?
I want to downsample the data to visualize it at around 1024 samples/sec. So I will run a generator making blocks of that size and plot 1 block per second. It's not enough to set the blocksize I also need the sample rate to be the blocksize as well and I also can process this into an array inside the import function and not change my current function calls.
I don't even need blocks until I want realtime so I can just return a downsampled array at import along with the full fidelity one.
Turns out you cannot downsample with soundfile.read since it reads the sample rate from the file unless it's raw input.
Let's perform the downsampling ourselves inside the import function and return 2 arrays as previous.
Downsample methods: Resample - Take every nth sample Bin - Average of Bins Interpolate - Fit curve
Preserving docstring for buffersize for later use buffer: buffer size for block generator [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384] or default None
So I would like to use both bins and interpolation to downsample the array for the analysis functions. I'll make a button for this in the magnitude spectrum plot at least possibly one in the spectrogram too.
Now the question is what kind of padding do I want to use for the last bin in case the length of the array isn't divisible by the bin size.
numpy padding options:
‘constant’ (default) Pads with a constant value. ‘edge’ Pads with the edge values of array. ‘linear_ramp’ Pads with the linear ramp between end_value and the array edge value. ‘maximum’ Pads with the maximum value of all or part of the vector along each axis. ‘mean’ Pads with the mean value of all or part of the vector along each axis. ‘median’ Pads with the median value of all or part of the vector along each axis. ‘minimum’ Pads with the minimum value of all or part of the vector along each axis. ‘reflect’ Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis. ‘symmetric’ Pads with the reflection of the vector mirrored along the edge of the array. ‘wrap’ Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning. ‘empty’ Pads with undefined values.
Also I think I just want to pad the last bin if possible. It seems numpy pad pads both start and end of the array.
Lengths of test arrays:
silence44100-infdBFS_Mono.aiff 441000
white88k-3dBFS.wav 2646001
hdchirp88k-3dBFS_lin.wav 44101
sin_44100100Hz-3dBFS_1s.wav 44101
hdsweep_1Hz44000Hz-3dBFS_30s.wav 2646001
silence44100-infdBFS_Stereo.aiff 441000
whitenoise_44100_0dBFS_Stereo.aiff 441000
hdchirp88k-3dBFS_lin_Stereo.aiff 44101
sin_44100440Hz-.8dBFS_Stereo.aiff 441000
Saija Original Mix.aiff 18050535
Turns out downsampling into bins does not significantly improve performance even when at very low fidelity (high bin sizes). The next step will be to try linear interpolation. If this fails then I will need to attempt blitting again probably alongside some kind of downsampling.
So I am not sure if linear interpolation will speed up the program too much since even heavily downsampled arrays still have performance issues. I believe the next step to be attempting blitting once more and trying to use the matplotlib doc methods for performance.
backend code for blitting:
# use backend that supports animation & blitting
mpl.use('Qt5Agg')
Blitting plotting, drawing, zoom, pan & buttons to speed up performance of especially visualizer function.