Answered
0
0

Hi,
I would like to translate this code in C #:

 FMOD::Sound *mySound = NULL;
    system->createSound("C:/media/drumloop.wav", FMOD_DEFAULT, NULL, &mySound);

    unsigned int lenBytes = 0;
    mySound->getLength(&lenBytes, FMOD_TIMEUNIT_PCMBYTES);

    void* myBuffer = NULL;
    mySound->lock(0, lenBytes, &myBuffer, NULL, &lenBytes, 0);

    //Now that we have the sound data in our buffer we need to work out what kind of data it is.
    int bitsPerSample = 0;
    mySound->getFormat(NULL, NULL, NULL, &bitsPerSample);

    if (bitsPerSample == 8)
    {
        char* sampleData = static_cast<char*>(myBuffer);
        //do stuff
    }
    else if (bitsPerSample == 16)
    {
        short* sampleData = static_cast<short*>(myBuffer);
        //do stuff
    }

I can’t translate this function : static_cast<char*>(myBuffer);
Thank you for your help.
Regards

  • You must to post comments
Best Answer
0
0

The best to access the data in C# is to copy it from unmanaged memory to mananged memory using the Marshal class. Once you’ve done that you can call Sound.unlock as you will no longer need the reference to the original data.

        uint lenin = 1024;
        IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero;
        uint lenout1 = 0, lenout2 = 0 ;
        sound1.@lock(0, lenin, ref ptr1, ref ptr2, ref lenout1, ref lenout2);

        if (bitsPerSample == 8)
        {
            sbyte[] data1 = new sbyte[lenout1];
            System.Runtime.InteropServices.Marshal.Copy(ptr1, (byte[])(Array)data1, 0, (int)lenout1);
            sbyte[] data2;
            if (ptr2 != IntPtr.Zero)
            {
                data2 = new sbyte[lenout2];
                System.Runtime.InteropServices.Marshal.Copy(ptr2, (byte[])(Array)data2, 0, (int)lenout2);
            }
        }
        else if (bitsPerSample == 16)
        {
            short[] data1 = new short[lenout1];
            System.Runtime.InteropServices.Marshal.Copy(ptr1, data1, 0, (int)(lenout1/sizeof(short)));

            short[] data2;                
            if (ptr2 != IntPtr.Zero)
            { 
                data2 = new short[lenout2];
                System.Runtime.InteropServices.Marshal.Copy(ptr2, data2, 0, (int)(lenout2/sizeof(short)));
            }
        }
  • You must to post comments
0
0

Thank you very much for this conversion, it works well but all values ​​of “data1[x]” and “data2[x]” (where “x” equal to lenght of “lenout”) are equal to 0. Even increasing the variable “lenin = 8192”.
An idea ?
Thanks!

  • Nicholas Wilcox
    Can you post your code. Not to be insulting, but are you sure your sound file doesn't start with silence?
  • You must to post comments
0
0
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
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 system = null;
        private FMOD.Channel channel = null;
        private FMOD.Sound sound = null;

        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 system);
            result = system.getVersion(ref version);
            if (version < FMOD.VERSION.number)
            {
                MessageBox.Show("Error!  old version of FMOD " + version.ToString("X") + ".  This program requiered " + FMOD.VERSION.number.ToString("X") + ".");
                Application.Exit();
            }
            result = system.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
            ERRCHECK(result);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FMOD.RESULT result;

            IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero;
            uint lenout1 = 0, lenout2 = 0, lenBytes = 0, lenin = 8192;
            FMOD.SOUND_FORMAT formatnull = 0;
            FMOD.SOUND_TYPE typenull = 0;
            int bitsPerSample = 0, intnull = 0, i = 0;

            result = system.createSound("Mysound.mp3", (FMOD.MODE.DEFAULT | FMOD.MODE.OPENONLY), ref sound);
            ERRCHECK(result);

            result = sound.getLength(ref lenBytes, FMOD.TIMEUNIT.PCMBYTES);
            ERRCHECK(result);

            result = sound.getFormat(ref typenull, ref formatnull, ref intnull, ref bitsPerSample);
            ERRCHECK(result);

            sound.@lock(0, lenBytes, ref ptr1, ref ptr2, ref lenout1, ref lenout2);

            if (bitsPerSample == 8)
            {
                sbyte[] data1 = new sbyte[lenout1];
                System.Runtime.InteropServices.Marshal.Copy(ptr1, (byte[])(Array)data1, 0, (int)lenout1);
                sbyte[] data2;
                if (ptr2 != IntPtr.Zero)
                {
                    data2 = new sbyte[lenout2];
                    System.Runtime.InteropServices.Marshal.Copy(ptr2, (byte[])(Array)data2, 0, (int)lenout2);
                }
            }
            else if (bitsPerSample == 16)
            {
                short[] data1 = new short[lenout1];
                System.Runtime.InteropServices.Marshal.Copy(ptr1, data1, 0, (int)(lenout1 / sizeof(short)));

                short[] data2;
                if (ptr2 != IntPtr.Zero)
                {
                    data2 = new short[lenout2];
                    System.Runtime.InteropServices.Marshal.Copy(ptr2, data2, 0, (int)(lenout2 / sizeof(short)));
                }
                for (i = 0; i < lenout1; i++)
                {
                    MessageBox.Show(" " + i + "/" + lenout1 + " " + data1[i]);    // all values are 0
                }

            }
            result = sound.unlock(ptr1, ptr2, lenout1, lenout2);
        }

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

Thanks for my help.

  • You must to post comments
0
0

Remove the OPENONLY flag to your createSound call. Or switch from lock() to readData().

  • You must to post comments
0
0

Great, it is progressing well. But now I encounter a small problem at the waveform of PictureBox1 :

Screenshot

Here is the code for displaying the waveform

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.Sound sound1 = null;
        uint lenBytes = 0;
        uint lenout1 = 0;
        sbyte[] peakdata_8b = null;
        short[] peakdata_16b = null;
        sbyte globalpeak_8b = 0;
        short globalpeak_16b = 0;

        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") + ".  This programm requiered " + FMOD.VERSION.number.ToString("X") + ".");
                Application.Exit();
            }
            result = system1.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
            ERRCHECK(result);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FMOD.RESULT result;

            IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero;
            uint lenout2 = 0;
            FMOD.SOUND_FORMAT formatnull = 0;
            FMOD.SOUND_TYPE typenull = 0;
            int bitsPerSample = 0, intnull = 0, i = 0;

            result = system1.createSound("C:/Kalimba.mp3", FMOD.MODE.DEFAULT, ref sound1);
            ERRCHECK(result);

            result = sound1.getLength(ref lenBytes, FMOD.TIMEUNIT.PCMBYTES);
            ERRCHECK(result);

            result = sound1.getFormat(ref typenull, ref formatnull, ref intnull, ref bitsPerSample);
            ERRCHECK(result);

            sound1.@lock(0, lenBytes, ref ptr1, ref ptr2, ref lenout1, ref lenout2);

            if (bitsPerSample == 8)
            {
                peakdata_8b = new sbyte[lenout1];
                System.Runtime.InteropServices.Marshal.Copy(ptr1, (byte[])(Array)peakdata_8b, 0, (int)lenout1);
                /*sbyte[] data2;
                if (ptr2 != IntPtr.Zero)
                {
                    data2 = new sbyte[lenout2];
                    System.Runtime.InteropServices.Marshal.Copy(ptr2, (byte[])(Array)data2, 0, (int)lenout2);
                }*/
            }
            else if (bitsPerSample == 16)
            {
                peakdata_16b = new short[lenout1];
                System.Runtime.InteropServices.Marshal.Copy(ptr1, peakdata_16b, 0, (int)(lenout1 / sizeof(short)));

                /*short[] data2;
                if (ptr2 != IntPtr.Zero)
                {
                    data2 = new short[lenout2];
                    System.Runtime.InteropServices.Marshal.Copy(ptr2, data2, 0, (int)(lenout2 / sizeof(short)));
                }*/

                /* Normalize max Peak : */
                for (i = 0; i < lenout1; i++)
                {
                    if (peakdata_16b[i] > globalpeak_16b)
                        globalpeak_16b = peakdata_16b[i];
                }
            }
            result = sound1.unlock(ptr1, ptr2, lenout1, lenout2);

            statusBar1.Text += " Done";
            pictureBox1.Refresh();
        }

        private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            if (peakdata_16b == null)
                return;
            Graphics g;
            g = e.Graphics;
            int i, j;
            float scaleh = globalpeak_16b / (pictureBox1.Height - 5) * 2;
            float scalew = ((lenout1 / 2) - 69000) / pictureBox1.Width;
            for (i = 0, j = 0; i < lenBytes && j < pictureBox1.Width; i = i + (int)scalew, j++)
                g.DrawLine(mypen, j, (pictureBox1.Height / 2), j, (pictureBox1.Height / 2) + (peakdata_16b[i] / scaleh));
        }

        private void ERRCHECK(FMOD.RESULT result)
        {
            if (result != FMOD.RESULT.OK)
            {
                timer1.Stop();
                MessageBox.Show("Error FMOD ! " + result + " - " + FMOD.Error.String(result));
                Environment.Exit(-1);
            }
        }
    }
}
  • You must to post comments
0
0

In fact, my problem is that the waveform is not correct unlike other audio processing software. I tried with sound_lock and sound_read and it gives the same thing.
I do not know how to manipulate the sample data to make a proper wave.
I know for a stereo sound 44100 Hz and 16 bits, a left/right pair (a sound with 2 channels) is called a sample. A sample = 4 bytes
ms = samples * 1000 / samplerate.
samples = ms * samplerate / 1000.
samplerate = samples * 1000 / ms.
bytes = samples * bits * channels / 8.
samples = bytes * 8 / bits / channels.

  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.