0
0

I’d like to build a waveform from an audio file. So i’m using sound::readData method. But could someone give me an example about using Array in reading data and/or convert structure between Int32[] and IntPtr?
btw I’m new to C#. I was using C++ and writing console programs so plz help, TIA!

regards,
MeteorRain

  • You must to post comments
0
0

solved. great thanks

  • You must to post comments
0
0

I’m sorry but I tried this code and I have a problem. It doesn’t work for me. I audiolength variable = 1. Here is my code. What’s wrong? What is the timer ? Thank you.

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using FMOD;

namespace App_test_waveform
{
    public partial class Form1 : Form
    {
        private FMOD.System system1 = null;
        private FMOD.Channel channel = null;
        private FMOD.Sound sound1 = null;
        private string curraudio = null;
        private short[] peakdata = null, weakdata = null;
        private uint samplerate;
        private float globalpeak;
        private uint audiolength;


    private Pen mypen = new Pen(Color.FromArgb(0x78, 0xc8, 0xa0));

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        uint version = 0;
        FMOD.RESULT result;

        /*Create a System object and initialize.*/
        result = FMOD.Factory.System_Create(ref system1);
        result = system1.getVersion(ref version);
        if (version < FMOD.VERSION.number)
        {
            MessageBox.Show("Error!  old version of Fmod " + version.ToString("X") + ".  Ce programme nécessite " + FMOD.VERSION.number.ToString("X") + ".");
            Application.Exit();
        }
        result = system1.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        FMOD.RESULT result;
        curraudio = "My_mp3.mp3";
        statusBar1.Text = "Opening File " + curraudio;
        result = system1.createSound(curraudio, (FMOD.MODE.HARDWARE & FMOD.MODE.ACCURATETIME), ref sound1);
        sound1.seekData(0);
        ERRCHECK(result);

        // build waveform data
        uint l1 = 0, l2 = 0;
        uint wscale = 1;
        sound1.getLength(ref l1, FMOD.TIMEUNIT.PCM);
        sound1.getLength(ref l2, FMOD.TIMEUNIT.MS);
        l1 = (uint)((ulong)l1 * 1000 / l2);
        l2 *= wscale;
        samplerate = l1 / wscale;
        short peak, weak;
        uint pos = 0, i;
        short[] buffer = new short[samplerate * 2];
        peakdata = new short[l2 / 1000 + 50];
        weakdata = new short[l2 / 1000 + 50];
        uint samplerateb = samplerate * 4;
        IntPtr buff = System.Runtime.InteropServices.Marshal.AllocHGlobal((int)samplerateb);
        do
        {
            sound1.readData(buff, samplerateb, ref l1);
            System.Runtime.InteropServices.Marshal.Copy(buff, buffer, 0, (int)samplerateb / 2);
            peak = weak = 0;
            for (i = 0; i < l1 / 4; i++)
            {
                if (buffer[i] > peak)
                    peak = buffer[i];
                if (buffer[i] < weak)
                    weak = buffer[i];
            }
            peakdata[pos] = peak;
            weakdata[pos] = weak;
            pos++;
            if (pos < (l2 / 1000 + 5) && pos % 500 == 0)
                statusBar1.Text = "Opening File " + curraudio + "  " + (pos * 100 / (l2 / 1000 + 5)) + "%";
            Application.DoEvents();
        } while (l1 == samplerateb);
        audiolength = pos;
        System.Runtime.InteropServices.Marshal.FreeHGlobal(buff);
        peak = 0;
        statusBar1.Text = "Normalizing audio...";
        for (i = 0; i < audiolength; i++)
        {
            if (peakdata[i] > peak)
                peak = peakdata[i];
            if (-weakdata[i] > peak)
                peak = (short)-weakdata[i];
        }
        globalpeak = peak;
        statusBar1.Text += " Done";
        pictureBox1.Refresh();
        system1.playSound(FMOD.CHANNELINDEX.FREE, sound1, true, ref channel);
        sound1.seekData(0);
    }

    private void ERRCHECK(FMOD.RESULT result)
    {
        if (result != FMOD.RESULT.OK)
        {
            timer1.Stop();
            MessageBox.Show("Erreur FMOD ! " + result + " - " + FMOD.Error.String(result));
            Environment.Exit(-1);
        }
    }

    private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        statusBar1.Text += audiolength;
        if (peakdata == null)
            return;
        Graphics g;
        g = e.Graphics;
        int i, j;
        float scale = globalpeak / (pictureBox1.Height - 30) * 2;
        for (i = 0, j = 0; i < audiolength && j < pictureBox1.Width; i++, j++)
            g.DrawLine(mypen, j, pictureBox1.Height / 2 + peakdata[i] / scale, j, pictureBox1.Height / 2 + weakdata[i] / scale);
    }
}
  • You must to post comments
0
0

Use the Marshal.Read* methods in the System.Runtime.InteropServices namespace

  • You must to post comments
0
0

Can you post some example code for us noobs? cheers.

  • You must to post comments
0
0

well, i’m new to C#.net so maybe the codes write ugly.
[code:21ws2f37]if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
if(curraudio != "")
{
sound.release();
peakdata = null;
weakdata = null;
}
hScrollBar1.Value = 0;
curraudio = openFileDialog1.FileName;
statusBar1.Text = "Opening File " + curraudio;
menuclosea.Enabled = true;
FMOD.RESULT result = system.createStream(curraudio, FMOD.MODE.HARDWARE & FMOD.MODE.ACCURATETIME, ref sound);
sound.seekData(0);
ERRCHECK(result);

// build waveform data
uint l1 = 0, l2 = 0;
sound.getLength(ref l1, FMOD.TIMEUNIT.PCM);
sound.getLength(ref l2, FMOD.TIMEUNIT.MS);
l1 = (uint)((ulong)l1 * 1000 / l2);
l2 *= wscale;
samplerate = l1 / wscale;
short peak, weak;
int pos = 0, i;
short[] buffer = new short[samplerate * 2];
peakdata = new short[l2 / 1000 + 50];
weakdata = new short[l2 / 1000 + 50];
uint samplerateb = samplerate * 4;
IntPtr buff = System.Runtime.InteropServices.Marshal.AllocHGlobal((int)samplerateb);
do
{
    sound.readData(buff, samplerateb, ref l1);
    System.Runtime.InteropServices.Marshal.Copy(buff, buffer, 0, (int)samplerateb / 2);
    peak = weak = 0;
    for(i = 0; i &lt; l1 / 4; i++)
    {
        if(buffer[i] &gt; peak)
            peak = buffer[i];
        if(buffer[i] &lt; weak)
            weak = buffer[i];
    }
    peakdata[pos] = peak;
    weakdata[pos] = weak;
    pos++;
    if(pos &lt; (l2 / 1000 + 5) &amp;&amp; pos % 500 == 0)
        statusBar1.Text = &quot;Opening File &quot; + curraudio + &quot;  &quot; + (pos * 100 / (l2 / 1000 + 5)) + &quot;%&quot;;
    Application.DoEvents();
} while (l1 == samplerateb);
audiolength = pos;
System.Runtime.InteropServices.Marshal.FreeHGlobal(buff);
peak = 0;
statusBar1.Text = &quot;Normalizing audio...&quot;;
for(i = 0; i &lt; audiolength; i++)
{
    if(peakdata[i] &gt; peak)
        peak = peakdata[i];
    if(-weakdata[i] &gt; peak)
        peak = (short)-weakdata[i];
}
globalpeak = peak;
statusBar1.Text += &quot; Done&quot;;
calcscrollbar();
pictureBox1.Refresh();
system.playSound(FMOD.CHANNELINDEX.FREE, sound, true, ref channel);
sound.seekData(0);

}[/code:21ws2f37]

  • You must to post comments
0
0

hey thanks.. do you have the code that draws the waveform onto the picturebox ? (is that what calcscrollbar() does? )

  • You must to post comments
0
0

Thanks for the example [b:2ptdx4vg]MeteorRain[/b:2ptdx4vg]. Later I will see as it works.

  • You must to post comments
0
0

[quote="danielm":2h934w7k]hey thanks.. do you have the code that draws the waveform onto the picturebox ? (is that what calcscrollbar() does? )[/quote:2h934w7k]
well, calcscrollbar() calcs the max value of the scroll bar, which i use to scroll the waveform.
then pictureBox1.Refresh() force the picturebox to redraw the area. and all redraw code are written here:
[code:2h934w7k]private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if(peakdata == null)
return;
Graphics g;
g = e.Graphics;
int i, j;
float scale = globalpeak / (pictureBox1.Height – 30) * 2;
for(i = hScrollBar1.Value * 100, j = 0; i < audiolength && j < pictureBox1.Width; i++, j++)
g.DrawLine(mypen, j, pictureBox1.Height / 2 + peakdata[i] / scale, j, pictureBox1.Height / 2 + weakdata[i] / scale);
if(currpos >= hScrollBar1.Value * 100 || currpos < (hScrollBar1.Value + pictureBox1.Width) * 100)
{
g.DrawLine(writepen, currpos – hScrollBar1.Value * 100, 0, currpos – hScrollBar1.Value * 100, pictureBox1.Height);
}
if(timer.Enabled)
{
if(playpos >= hScrollBar1.Value * 100 && playpos < (hScrollBar1.Value * 100 + pictureBox1.Width))
{
g.DrawLine(writepen, playpos – hScrollBar1.Value * 100, pictureBox1.Height / 5, playpos – hScrollBar1.Value * 100, pictureBox1.Height * 4 / 5);
}
else if(playpos < hScrollBar1.Value * 100)
hScrollBar1.Value–;
else
hScrollBar1.Value += 5;
}
}[/code:2h934w7k]

and

[code:2h934w7k]private Pen mypen = new Pen(Color.FromArgb(0x78, 0xc8, 0xa0));
private Pen writepen = new Pen(Color.White);
[/code:2h934w7k]

  • You must to post comments
0
0

Thanks heaps: I have it working in dotnet 2.0 now… I’m just trying to figure out the scrollbar bit.

  • You must to post comments
0
0

ooohh… got it all working, thankyou so much.

  • You must to post comments
Showing 10 results
Your Answer

Please first to submit.