Plotting the audio amplitude as fast as it is received is not the best way to visualize the waveform. You can improve the visualizer's depiction of the waveform shape by taking advantage of a simple equation. Let me explain

frequency * wavelength = sample-rate

// perform this update 60 times per second
x_1 = x_0 + 44100/60
// which is the same as this
x_1 = x_0 + sample-rate / frequency
// and this
x_1 = x_0 + wavelength

You can see that if we choose wavelength correctly when visualizing a 60hz sin wave, then each successive chunk of waveform that we visualize will contain the waveform in roughly the same spot, i.e. the phase of the waveform in our visualizer buffer will change minimally. The effect this has is that the user watching the visualization is presented with a clean and consistent image of the shape of the waveform, in this case a 60hz sin wave.

Of course, if you change the wavelength that you step x_n forward by, then you would have to change the amount of times per second that you step x_n forward in order to stay in sync with audio playback. You can restrict this update period to some range between 30 - 60 frames per second by using the fact that for any distance in the buffer that we choose to step x by that minimizes the phase change of the visualized waveform, an integer multiple of that distance also minimizes the phase change of the visualized waveform (assuming a constant frequency, which I've found to be an ok assumption to make in practice).

So if our waveform is a 1000hz sine wave, then we would need to step x forward by 44100/1000 = 44.1 samples per update, and in order to stay in sync with the audio play back we would have to do this 44100/44.1 = 1000 times per second. To reduce the number of times per second that we have to move x forward, we can just take larger steps that are integer multiples of the wavelength. We need to choose a step size to take such that the number of steps we need to take per second is roughly 60. So for a given frequency F and sample-rate SR we solve for n in 60 = SR / (n * SR/F) --> 60 = F/n --> n = F/60 and n must be integer so let n = ceil(F/60). Now we can step x forward by x_1 = x_0 + n * wavelength. Because we force n to be integer, the amount we step x forward by will cause x to not be perfectly in sync with the audio playback, so we would have to check how out of sync we are every so often and then adjust our position. Also, to give the appearance that the waveform updates at 60fps you can perform some smoothing between each successive visualization buffer.

I may have missed some details or made some errors here, but the point is that there is a way to give the user a better view of the shape of the waveform.
Here is my git project that implements these ideashttps://github.com/xdaimon/music_vis...ster/pulse.cpp
If you checkout the git project, do a 'git checkout waveform_mode' first, (otherwise the app will be like an oscilloscope in xy mode)