public class FMODStreamPlayer { public PCMAudioProducer audioProducer; public uint bufferSize = 8192; public float gain = 0.5f; public static int toneFrequency = 120; FMOD.System fmodSystem; Sound sound; public FMODStreamPlayer(PCMAudioProducer producer) { audioProducer = producer; fmodSystem = FMODUnity.RuntimeManager.LowlevelSystem; audioProducer.Created += CreateStream; audioProducer.Play += PlayStream; audioProducer.Pause += PauseStream; audioProducer.Close += CloseStream; } ~FMODStreamPlayer() { if (audioProducer != null) { audioProducer.Created -= CreateStream; audioProducer.Play -= PlayStream; audioProducer.Pause -= PauseStream; audioProducer.Close -= CloseStream; } } void CreateStream(int channels, int bitDepth, int frequency) { UnityEngine.Debug.Log("create fmod stream"); CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO(); exinfo.decodebuffersize = bufferSize; exinfo.length = 8192; exinfo.numchannels = channels; exinfo.defaultfrequency = frequency; exinfo.format = SOUND_FORMAT.PCM16; exinfo.pcmreadcallback = pcmreadcallback; exinfo.pcmsetposcallback = DoSetPos; exinfo.suggestedsoundtype = SOUND_TYPE.RAW; RESULT r = fmodSystem.createStream(String.Empty, MODE.OPENUSER | MODE.LOOP_NORMAL, ref exinfo, out sound); if (r != 0) { UnityEngine.Debug.LogError("Error: " + r); return; } } RESULT pcmreadcallback(IntPtr soundraw, IntPtr data, uint datalen) { //UnityEngine.Debug.Log("PCMReadCallback from FMOD"); //UnityEngine.Debug.Log("Thread id = " + Thread.CurrentThread.ManagedThreadId); byte[] bytes; int receivedBytes; bool success = audioProducer.GetAudioBytes((int)datalen, out bytes, out receivedBytes); short[] shorts = new short[bytes.Length / 2]; PCMConverter.BytesToShorts(bytes, ref shorts); Sound sound = new Sound(soundraw); Marshal.Copy(shorts, 0, data, shorts.Length); return RESULT.OK; } void PlayStream() { UnityEngine.Debug.Log("Play fmod stream"); Channel channel; fmodSystem.playSound(sound, null, false, out channel); } void PauseStream() { UnityEngine.Debug.Log("Pause fmod stream"); Channel channel; fmodSystem.playSound(sound, null, true, out channel); } void CloseStream() { UnityEngine.Debug.Log("Close fmod stream"); sound.release(); } RESULT DoSetPos(IntPtr soundraw, int subsound, uint position, FMOD.TIMEUNIT postype) { return FMOD.RESULT.OK; } } public class PCMAudioGenerator : PCMAudioProducer { public int sampleRate = 48000; public int toneFrequency = 480; public override bool GetAudioBytes(int bufferSize, out byte[] bytes, out int receivedBytes) { //Debug.Log("Getting test audio bytes. Amount = " + numBytes); receivedBytes = bufferSize; bytes = new byte[bufferSize]; double multiplier = ((double)sampleRate / (double)toneFrequency) / (2 * Math.PI); for (int i = 0; i < bytes.Length; i += 2) { short sample = (short)(Math.Sin((i) / multiplier) * short.MaxValue) ; byte[] sampleBytes = BitConverter.GetBytes(sample); bytes[i] = sampleBytes[1]; // little endian bytes[i + 1] = sampleBytes[0]; } return true; } … }