Also, if this helps anyone… I tried getting a version working with just one fmod system and writing to a file while locking/unlocking the audio. While it worked, it had a few pops in audio here and there, so I prob got something wrong, but I’ll post anyway in case this helps anyone in the future.
static void SingleSystemVersion()
{
CREATESOUNDEXINFO exInfo = new CREATESOUNDEXINFO();
exInfo.cbsize = Marshal.SizeOf(typeof(CREATESOUNDEXINFO));
exInfo.numchannels = 1;
exInfo.format = SOUND_FORMAT.PCM16;
exInfo.defaultfrequency = 44100;
exInfo.length = (uint)exInfo.defaultfrequency * sizeof(short) * (uint)exInfo.numchannels * 2;
Factory.System_Create(out FMOD.System micRecordSystem);
micRecordSystem.init(32, INITFLAGS.NORMAL, IntPtr.Zero);
Console.WriteLine("Press any key to record");
Console.ReadKey();
micRecordSystem.createSound(exInfo.userdata, MODE.LOOP_NORMAL | MODE.OPENUSER, ref exInfo, out Sound Sound);
micRecordSystem.recordStart(0, Sound, true);
FileStream fs = File.Create("record.wav");
BinaryWriter bw = new BinaryWriter(fs);
uint soundLength, dataLength = 0;
WriteWavHeader(bw, Sound, dataLength);
Sound.getLength(out soundLength, TIMEUNIT.PCM);
uint lastRecordPos = 0;
Console.WriteLine("Press any key to stop");
while (!Console.KeyAvailable)
{
uint recordPos;
micRecordSystem.getRecordPosition(0, out recordPos);
if (recordPos != lastRecordPos)
{
IntPtr ptr1, ptr2;
int blockLength;
uint length1, length2;
blockLength = (int)recordPos - (int)lastRecordPos;
if (blockLength < 0)
{
blockLength += (int)soundLength;
}
Sound.@lock(lastRecordPos * (uint)exInfo.numchannels * 2, (uint)blockLength * (uint)exInfo.numchannels * 2, out ptr1, out ptr2, out length1, out length2);
if (ptr1 != IntPtr.Zero && length1 > 0)
{
byte[] bytes = new byte[length1];
Marshal.Copy(ptr1, bytes, 0, (int)length1);
fs.Write(bytes, 0, (int)length1);
dataLength += length1;
}
if (ptr2 != IntPtr.Zero && length2 > 0)
{
byte[] bytes = new byte[length2];
Marshal.Copy(ptr2, bytes, 0, (int)length2);
fs.Write(bytes, 0, (int)length2);
dataLength += length2;
}
Sound.unlock(ptr1, ptr2, length1, length2);
}
lastRecordPos = recordPos;
micRecordSystem.update();
System.Threading.Thread.Sleep(16);
}
WriteWavHeader(bw, Sound, dataLength);
bw.Close();
fs.Close();
micRecordSystem.recordStop(0);
Sound.release();
micRecordSystem.close();
micRecordSystem.release();
Console.WriteLine("Done!");
}
static void WriteWavHeader(BinaryWriter bw, Sound sound, uint dataLength)
{
sound.getFormat(out _, out _, out int numChannels, out int bits);
sound.getDefaults(out float sampleRate, out _);
bw.Seek(0, SeekOrigin.Begin);
bw.Write(System.Text.Encoding.ASCII.GetBytes("RIFF")); //RIFF 4 bytes chars
bw.Write(32 + dataLength); //File Size (after this chunk) 4 bytes int (32 for rest of header + wave data)
bw.Write(System.Text.Encoding.ASCII.GetBytes("WAVEfmt ")); //WAVEfmt 8 bytes chars
bw.Write(16); //Length of above fmt data 4 bytes int
bw.Write((short)1); //Fomrat 1 is PCM 2 bytes short
bw.Write((short)numChannels); //Number of Channels 2 bytes short
bw.Write((int)sampleRate); //Sample Rate 4 bytes int
bw.Write((int)(sampleRate * bits / 8 * numChannels)); // 4 bytes int
bw.Write((short)(bits / 8 * numChannels)); // 2 bytes short
bw.Write((short)bits); //Bits per sample 2 bytes short
bw.Write(System.Text.Encoding.ASCII.GetBytes("data")); //data 4 bytes chars
bw.Write(dataLength); //Size of data section 4 bytes int
}