NAudio.WaveFormRenderer icon indicating copy to clipboard operation
NAudio.WaveFormRenderer copied to clipboard

ArgumentException: Must read complete blocks: requested 35310, block align is 4

Open MrKsiJ opened this issue 2 years ago • 3 comments

image

MrKsiJ avatar Nov 20 '22 21:11 MrKsiJ

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.

MrKsiJ avatar Nov 20 '22 21:11 MrKsiJ

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);
    }

DAVIDSystems avatar Mar 11 '23 09:03 DAVIDSystems

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
};

mitssi avatar May 11 '24 15:05 mitssi