Skip to content

Instantly share code, notes, and snippets.

@haydenjameslee
Created January 24, 2016 05:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haydenjameslee/3e20983cf5530e878a98 to your computer and use it in GitHub Desktop.
Save haydenjameslee/3e20983cf5530e878a98 to your computer and use it in GitHub Desktop.
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment