How to visualize a sound form?

  • Is there any audio / programming related stack exchange site?
  • I am trying to make wave form in WinForms
  • Which algorithm should I use?

For example, if I have 200 samples per pixel (vertical line), should I draw the lowest and highest sample from this part of the 200 samples? Or should I collect an average number of low and high samples? Maybe both in different colors?

+4
source share
4 answers
  • Try dsp.stackexchange.com

  • With 200 samples per pixel, you can try several approaches. No matter what you do, it is often best to draw each vertical line both above and below 0, i.e. process positive and negative sample values ​​separately. Most likely, the easiest way to calculate the RMS. With such low-resolution peak values, you are likely to get the wrong representation of the waveform.

+6
source

This will help you generate a signal from an audio file using nAudio in C # ...

using NAudio.Wave; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string strPath = Server.MapPath("audio/060.mp3"); string SongID = "2"; byte[] bytes = File.ReadAllBytes(strPath); WriteToFile(SongID,strPath, bytes); Response.Redirect("Main.aspx"); } private void WriteToFile(string SongID, string strPath, byte[] Buffer) { try { int samplesPerPixel = 128; long startPosition = 0; //FileStream newFile = new FileStream(GeneralUtils.Get_SongFilePath() + "/" + strPath, FileMode.Create); float[] data = FloatArrayFromByteArray(Buffer); Bitmap bmp = new Bitmap(1170, 200); int BORDER_WIDTH = 5; int width = bmp.Width - (2 * BORDER_WIDTH); int height = bmp.Height - (2 * BORDER_WIDTH); NAudio.Wave.Mp3FileReader reader = new NAudio.Wave.Mp3FileReader(strPath, wf => new NAudio.FileFormats.Mp3.DmoMp3FrameDecompressor(wf)); NAudio.Wave.WaveChannel32 channelStream = new NAudio.Wave.WaveChannel32(reader); int bytesPerSample = (reader.WaveFormat.BitsPerSample / 8) * channelStream.WaveFormat.Channels; using (Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.White); Pen pen1 = new Pen(Color.Gray); int size = data.Length; string hexValue1 = "#009adf"; Color colour1 = System.Drawing.ColorTranslator.FromHtml(hexValue1); pen1.Color = colour1; Stream wavestream = new NAudio.Wave.Mp3FileReader(strPath, wf => new NAudio.FileFormats.Mp3.DmoMp3FrameDecompressor(wf)); wavestream.Position = 0; int bytesRead1; byte[] waveData1 = new byte[samplesPerPixel * bytesPerSample]; wavestream.Position = startPosition + (width * bytesPerSample * samplesPerPixel); for (float x = 0; x < width; x++) { short low = 0; short high = 0; bytesRead1 = wavestream.Read(waveData1, 0, samplesPerPixel * bytesPerSample); if (bytesRead1 == 0) break; for (int n = 0; n < bytesRead1; n += 2) { short sample = BitConverter.ToInt16(waveData1, n); if (sample < low) low = sample; if (sample > high) high = sample; } float lowPercent = ((((float)low) - short.MinValue) / ushort.MaxValue); float highPercent = ((((float)high) - short.MinValue) / ushort.MaxValue); float lowValue = height * lowPercent; float highValue = height * highPercent; g.DrawLine(pen1, x, lowValue, x, highValue); } } string filename = Server.MapPath("image/060.png"); bmp.Save(filename); bmp.Dispose(); } catch (Exception e) { } } public float[] FloatArrayFromStream(System.IO.MemoryStream stream) { return FloatArrayFromByteArray(stream.GetBuffer()); } public float[] FloatArrayFromByteArray(byte[] input) { float[] output = new float[input.Length / 4]; for (int i = 0; i < output.Length; i++) { output[i] = BitConverter.ToSingle(input, i * 4); } return output; } } 
+6
source

You can use AudioControl from the project code.

and see this: Generating various audio signals in C #

These projects may be useful for you if you are initially implementing your code:

+1
source

Including any user in this:

You can process the samples per pixel as a zoom level, at higher levels (increased more) you probably want to query this for performance reasons.

Most likely, you will need a fixed width that fits the screen to draw and use virtual scrolling (so you don’t have a potential drawing area of ​​several million pixels).

You can calculate the value for each pixel by iterating over the audio data with: skip (scroll position * samples per pixel) + (pixel * samples per pixel), samples per pixel. This allows you to use infinite zoom and scroll, as you only read and draw the minimum amount to fill the view. The scroll width is calculated with the length of the audio data / samples per pixel.

Audio samples are typically shown in one of two ways: peak sample range or rms. The average value is calculated by summing the squares of all values ​​in the sampling range, dividing the sum by the length of the sample, the rms value, if the square of it (the rms value is slightly higher than the average and is a good measure of perceived loudness)

You can increase productivity in several ways, such as increasing sub-sampling (causing loss of detail), throttling the scroll, and canceling the cancellation of drawing requests if there are new visual scrolling before displaying the previous one.

0
source

Source: https://habr.com/ru/post/885848/


All Articles