0
0

I’m trying to get a real-time, accurate waveform of a sound using sound.@lock to use in a BPM calculator. I might be missing something, but when I’m using sound.@lock, I’m able to access the data, but the values I’m getting in are not what I’m expecting. Here’s a snippet of my code:
[code:1ls8cgc3]
sound.getLength(ref len,FMOD.TIMEUNIT.PCMBYTES);
channel.getPosition(ref playPos,FMOD.TIMEUNIT.PCMBYTES);
FMOD.RESULT result;

            if(playPos != lastPlayPos)
            {

                uint chunkDiff = playPos-lastPlayPos;
                IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero;
                uint len1 = 0, len2 = 0;
                sound.@lock(lastPlayPos, chunkDiff, ref ptr1, ref ptr2, ref len1, ref len2); //4 = stereo 16bit.  1 sample = 4 bytes. 
                if (ptr1 != IntPtr.Zero && len1 > 0)
                {
                    if(bufferCount + (int)len1 <= bufferTmp.Length)
                    {
                        Marshal.Copy(ptr1, bufferTmp, bufferCount, (int)len1);
                        bufferCount += (int)len1;

                    }
                    else
                    {
                        int remain = bufferTmp.Length - bufferCount;
                        try
                        {
                            Marshal.Copy(ptr1, bufferTmp, bufferCount, remain);
                            calculate(bufferTmp);
                            int extra = bufferTmp.Length - remain;
                            Array.Copy(bufferTmp,bufferCount,bufferTmp,0,extra);//SHIFT EVERYTHING TO THE BEGINNING
                            bufferCount = extra;
                            Array.Clear(bufferTmp,bufferCount,bufferTmp.Length-bufferCount);
                        }
                        catch(Exception ex)
                        {
                            Console.WriteLine(ex.ToString());
                        }
                    }  
                }
                if (ptr2 != IntPtr.Zero && len2 > 0)
                {

                }
            }
            lastPlayPos = playPos;

[/code:1ls8cgc3]
The float values that I’m receiving bufferTmp are either on the order of 1.0-38, 1.0+38, or NaN. Am I not converting the bytes properly to float values, or is there something wlse wrong? This script is on a timer and runs 10X per second.

  • You must to post comments
0
0

I’ve tried using getWaveData. Trouble is, I can’t build an accurate waveform buffer (need it to be ~3 seconds) using this method. I’m either getting overlapping data or bits are getting truncated and is a real mess. I figured out that in my initial code, I was marshalling straight to the float array instead of a byte array first from the pointer, then the float array. I guess I have to just mess with it a bit more. i really just need a heavily downsampled version of the data, around 640 samples/second as opposed to 22050 for uncompressed 1-channel PCM data.

Another problem I was running into was lags every couple of sound.lock passes, and when it caught up was trying to feed too much data into the BPM algorithm, since it only is built to handle set buffer sizes. Finally, it seems that the amount of data returned using sound.lock will depend also on the bitrate of the sound. So, if it’s a variable bitrate MP3, it’s going to be hard to determine what exactly is 3 seconds worth of data anyway. Is this correct?

  • You must to post comments
0
0

Would somebody mind posting sample code showing the correct way to get the entire waveform for a sound using sound.@lock in C#? Much apreciated. Michael

  • You must to post comments
0
0

Thanks Brett,
I’m pretty new to audio programming: once I have the rawdata (byte array) I gather its just a case of analysing the data using a formula similar to that posted [url=http://www.fmod.org/forum/viewtopic.php?t=4001&highlight=lock:3txcqrvf]here[/url:3txcqrvf]?

  • You must to post comments
0
0

Hmm.. I have another issue. The rawdata array contains bytes of the same value. For example: a PCM16 .mp3 or .wav file returns all zeros while a PCM8 .wav file returns all values set to 128.
have I missed something?
[code:46hutuku]
result = system.init(1, FMOD.INITFLAG.NORMAL, (IntPtr)null);
string url = @"C:\drumloop.wav";
//string url = @"C:\mlkihaveadream35348.mp3";
//string url = @"C:\jaguar.wav";
//string url = @"C:\test1.mp3";
//string url = @"C:\HeadAt.mp3";

        uint length = 0;
        result = system.createSound(url, FMOD.MODE.OPENONLY | FMOD.MODE.ACCURATETIME, ref sound);
        result = sound.getLength(ref length, FMOD.TIMEUNIT.PCMBYTES);

        IntPtr ptr1 = IntPtr.Zero;
        IntPtr ptr2 = IntPtr.Zero;
        uint len1 = 0;
        uint len2 = 0;

        sound.@lock(0, length, ref ptr1, ref ptr2, ref len1, ref len2);
        byte[] rawdata = new byte[len1];
        System.Runtime.InteropServices.Marshal.Copy(ptr1, rawdata, 0, (int)len1);
        sound.unlock(ptr1, ptr2, len1, len2);

[/code:46hutuku]

Any ideas what I am doing wrong?

  • You must to post comments
0
0

Somebody could post an definitive example that works? It seems that there are many doubts with this subject… In C#? :roll:

  • You must to post comments
0
0

That would be greatly appreciated. 😀

  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.