0
0

I am using the FMOD API integrated with Unity to do realtime audio recording and playback in unity3d. The aim of our FMOD code is to record the audio and pass small chunks (10 – 20ms) to other parts of the code to be processed.

public override bool Initialise() {

    FmodCheck(mSystem.init(32, FMOD.INITFLAGS.NORMAL, (System.IntPtr)null));

    //Prevents drivers returning 0 for first second after Initialisation
    Thread.Sleep(1000);

    int numDrivers = 0, numConnected = 0;
    if (!initialised && FmodCheck(mSystem.getRecordNumDrivers(out numDrivers, out numConnected)) && numDrivers + numConnected > 0) {

        Guid guid;
        StringBuilder nameBuilder = new StringBuilder();
        FMOD.SPEAKERMODE speakerMode;
        FMOD.DRIVER_STATE driverState;

        if (FmodCheck(mSystem.getRecordDriverInfo(mDeviceIndex, nameBuilder, 0, out guid, out mRate, out speakerMode, out mChannels, out driverState))) {
            mChannels = 1;
            mRate = (int)inputFrequency;

            // 2.0f for the byte size of PCM16.
            mByteCount = (uint)(kRecordSeconds * (float)(mChannels * mRate) * 2.0);
            mBytes = new byte[mByteCount];

            FMOD.CREATESOUNDEXINFO info = new FMOD.CREATESOUNDEXINFO();
            info.cbsize = Marshal.SizeOf(info);
            info.numchannels = mChannels;
            info.defaultfrequency = mRate;
            info.format = FMOD.SOUND_FORMAT.PCM16;
            info.length = mByteCount;


            FmodCheck(mSystem.createSound(mBytes, FMOD.MODE.OPENMEMORY_POINT | FMOD.MODE.OPENRAW, ref info, out mSound));

            mSound.getLength(out mLength, FMOD.TIMEUNIT.PCM);

            initialised = true;
        }
    }
    return initialised; 
    StartInput();

}

public void Listen() {
        lock (this) {
            while (@continue && initialised && StartedInput) {
                uint pos;
                mSystem.getRecordPosition(mDeviceIndex, out pos); //Position in PCM_16 samples
                pos *= 2U; //PCM_16 samples to number of bytes                      

                uint playDelta = (pos >= lastPlayPos) ? (pos - lastPlayPos) : (pos + (uint)(mRate * kRecordSeconds * mChannels * 2U) - lastPlayPos);

                if (playDelta > 0) {

                    IntPtr buffer, bufferWrap;
                    uint length, lengthWrap;
                    mSound.@lock(pos, playDelta, out buffer, out bufferWrap, out length, out lengthWrap);

                    managedBuffer = new byte[length];
                    Marshal.Copy(buffer, managedBuffer, 0, (int)length);

                    engineTarget.AddAudio(managedBuffer);

                    GC.AddMemoryPressure(length);

                    if (bufferWrap != IntPtr.Zero && lengthWrap != 0) {
                        managedBuffer = new byte[lengthWrap];
                        Marshal.Copy(bufferWrap, managedBuffer, 0, (int)lengthWrap);

                        engineTarget.AddAudio(managedBuffer);

                        GC.AddMemoryPressure(length);
                    }

                    mSystem.update();
                    mSound.unlock(buffer, bufferWrap, length, lengthWrap);
                    lastPlayPos = pos;
                }

                totalData += playDelta;
                Thread.Sleep(10)
            }
        }
    }

The code to do this is rather straight-forward and we’ve been using it successfully on Windows for some time, in the past week I’ve switched over to developing for OSX as well and noticed that it wasn’t working on my 2011 Macbook Pro (Dual-core i5 2.4GHz, 16GB RAM, v10.12.5) I then tried it on a 2013 iMac, a 2013 Macbook pro and a 2011 Mac Mini and it worked fine on the two devices from 2013 and stuttered on the two devices from 2011.

Every iteration through the loop should be returning at least 10ms of audio and the playDelta value should be at least 882 bytes (10ms @ 44.1kHz) however two out of every three loops is returning a play delta of zero having not recorded any audio.

Has anyone experienced this issue before or know of a way to fix it?

  • Cameron Baron

    Not something we have experienced before. Do you get the same issue when using the Studio API examples?

  • You must to post comments
Showing 0 results
Your Answer

Please first to submit.