NAudio.WaveFormRenderer
NAudio.WaveFormRenderer copied to clipboard
ArgumentException: Must read complete blocks: requested 35310, block align is 4
The problem arises with the picker, I tried different picker strategies, they all fail, but I need to get a picture of the sound wave from the file. The file is successfully converted to a WAV file from MP3 and its wave can also be obtained in the Audacity program, but I need a wave in the form of an image. I've looked at some examples of how to do this, however I need help with this issue.
It works with the following Patch in public class WaveFormRenderer. samplePerPixel may not be uneven (because stepSize can be uneven too)
public Image Render(WaveStream waveStream, IPeakProvider peakProvider, WaveFormRendererSettings settings)
{
int bytesPerSample = (waveStream.WaveFormat.BitsPerSample / 8);
var samples = waveStream.Length / (bytesPerSample);
var samplesPerPixel = (int)(samples / settings.Width);
/**/ Patch Start
int rest = samplesPerPixel % bytesPerSample;
if (rest > 0)
{
samplesPerPixel += rest;
}
// Patch End**
var stepSize = settings.PixelsPerPeak + settings.SpacerPixels;
peakProvider.Init(waveStream.ToSampleProvider(), samplesPerPixel * stepSize);
return Render(peakProvider, settings);
}
The issue arises because the ReadBuffer size in the Render function isn't a multiple of bytesPerSample.
This can be easily fixed by adjusting the PixelsPerPeak size from 2 to 3 in the GetRendererSettings function. By making this change, the total size of PixelsPerPeak + SpacerPixels becomes even, ensuring that the ReadBuffer size is a multiple of bytesPerSample.
Here is how you can adjust the settings in the SoundCloudBlockWaveFormSettings:
var soundCloudOrangeTransparentBlocks = new SoundCloudBlockWaveFormSettings(Color.FromArgb(196, 197, 53, 0), topSpacerColor, Color.FromArgb(196, 79, 26, 0),
Color.FromArgb(64, 79, 79, 79))
{
Name = "SoundCloud Orange Transparent Blocks",
PixelsPerPeak = 3, // was 2
SpacerPixels = 1,
TopSpacerGradientStartColor = topSpacerColor,
BackgroundColor = Color.Transparent
};