} // loading jingle private void GetRawData(FMOD.Sound tempSound, int channels, int bits, uint pcm) { tempSound.CheckNull("tempSound"); uint len1 = 0, len2 = 0; IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero; switch (bits) { case 16: { FMOD.RESULT result = tempSound.@lock(0, (uint)(pcm * channels * sizeof(short)), ref ptr1, ref ptr2, ref len1, ref len2); ErrorCheck(result); SoundDataBuffer = new CircularBuffer((int)(pcm * channels)); Marshal.Copy(ptr1, SoundDataBuffer.Buffer, 0, (int)(len1 / sizeof(short))); if (len2 > 0) { Marshal.Copy(ptr2, SoundDataBuffer.Buffer, (int)(len1 / sizeof(short)), (int)(len2 / sizeof(short))); } tempSound.unlock(ptr1, ptr2, len1, len2); break; } default: throw new InvalidOperationException("Bits count unsupported"); } }
int AddSample(FMOD.Sound sound, string name) { if (samples.Contains(sound)) { return(samples.IndexOf(sound)); } // Get properties sound.getLength(out uint length, FMOD.TIMEUNIT.PCMBYTES); sound.getLoopPoints(out uint loop_start, FMOD.TIMEUNIT.PCMBYTES, out uint loop_end, FMOD.TIMEUNIT.PCMBYTES); sound.getLoopCount(out int loopCount); sound.getDefaults(out float frequency, out int priority); // Get sample data sound.@lock(0, length, out IntPtr snd, out IntPtr idc, out uint len, out uint idc2); var pcm8 = new byte[len]; Marshal.Copy(snd, pcm8, 0, (int)len); sound.unlock(snd, idc, len, idc2); short[] pcm16 = pcm8.Select(i => (short)(i << 8)).ToArray(); // Add to file sf2.AddSample(pcm16, name, loopCount == -1, loop_start, (uint)frequency, 60, 0); samples.Add(sound); return(samples.Count - 1); }
private void timer_Tick(object sender, System.EventArgs e) { FMOD.RESULT result; if (recording) { uint recordpos = 0; result = system.getRecordPosition(selected, ref recordpos); ERRCHECK(result); if (recordpos != lastrecordpos) { IntPtr ptr1 = IntPtr.Zero, ptr2 = IntPtr.Zero; int blocklength; uint len1 = 0, len2 = 0; blocklength = (int)recordpos - (int)lastrecordpos; if (blocklength < 0) { blocklength += (int)soundlength; } /* * Lock the sound to get access to the raw data. */ sound.@lock(lastrecordpos * 4, (uint)blocklength * 4, ref ptr1, ref ptr2, ref len1, ref len2); /* *4 = stereo 16bit. 1 sample = 4 bytes. */ /* * Write it to disk. */ if (ptr1 != IntPtr.Zero && len1 > 0) { byte[] buf = new byte[len1]; Marshal.Copy(ptr1, buf, 0, (int)len1); datalength += (int)len1; fs.Write(buf, 0, (int)len1); } if (ptr2 != IntPtr.Zero && len2 > 0) { byte[] buf = new byte[len2]; Marshal.Copy(ptr2, buf, 0, (int)len2); datalength += (int)len2; fs.Write(buf, 0, (int)len2); } /* * Unlock the sound to allow FMOD to use it again. */ sound.unlock(ptr1, ptr1, len1, len2); } lastrecordpos = recordpos; statusBar.Text = "Record buffer pos = " + recordpos + " Record time = " + datalength / 44100 / 4 / 60 + ":" + (datalength / 44100 / 4) % 60; } if (system != null) { system.update(); } }
private void SaveToWav() { FileStream fs = null; int channels = 0, bits = 0; float rate = 0; IntPtr ptr1 = new IntPtr(), ptr2 = new IntPtr(); uint lenbytes = 0, len1 = 0, len2 = 0; FMOD.SOUND_TYPE type = FMOD.SOUND_TYPE.WAV; FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int temp1 = 0; float temp3 = 0; if (sound == null) { return; } sound.getFormat(ref type, ref format, ref channels, ref bits); sound.getDefaults(ref rate, ref temp3, ref temp3, ref temp1); sound.getLength(ref lenbytes, FMOD.TIMEUNIT.PCMBYTES); FmtChunk fmtChunk = new FmtChunk(); DataChunk dataChunk = new DataChunk(); WavHeader wavHeader = new WavHeader(); RiffChunk riffChunk = new RiffChunk(); fmtChunk.chunk = new RiffChunk(); fmtChunk.chunk.id = new char[4]; fmtChunk.chunk.id[0] = 'f'; fmtChunk.chunk.id[1] = 'm'; fmtChunk.chunk.id[2] = 't'; fmtChunk.chunk.id[3] = ' '; fmtChunk.chunk.size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk); fmtChunk.wFormatTag = 1; fmtChunk.nChannels = (ushort)channels; fmtChunk.nSamplesPerSec = (uint)rate; fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8); fmtChunk.nBlockAlign = (ushort)(1 * channels * bits / 8); fmtChunk.wBitsPerSample = (ushort)bits; dataChunk.chunk = new RiffChunk(); dataChunk.chunk.id = new char[4]; dataChunk.chunk.id[0] = 'd'; dataChunk.chunk.id[1] = 'a'; dataChunk.chunk.id[2] = 't'; dataChunk.chunk.id[3] = 'a'; dataChunk.chunk.size = (int)lenbytes; wavHeader.chunk = new RiffChunk(); wavHeader.chunk.id = new char[4]; wavHeader.chunk.id[0] = 'R'; wavHeader.chunk.id[1] = 'I'; wavHeader.chunk.id[2] = 'F'; wavHeader.chunk.id[3] = 'F'; wavHeader.chunk.size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + lenbytes); wavHeader.rifftype = new char[4]; wavHeader.rifftype[0] = 'W'; wavHeader.rifftype[1] = 'A'; wavHeader.rifftype[2] = 'V'; wavHeader.rifftype[3] = 'E'; fs = new FileStream("record.wav", FileMode.Create, FileAccess.Write); /* * Write out the WAV header. */ IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader)); IntPtr fmtChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk)); IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk)); byte [] wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)]; byte [] fmtChunkBytes = new byte[Marshal.SizeOf(fmtChunk)]; byte [] dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)]; Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false); Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false); Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); Marshal.StructureToPtr(dataChunk, dataChunkPtr, false); Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); fs.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); fs.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); fs.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); /* * Lock the sound to get access to the raw data. */ sound.@lock(0, lenbytes, ref ptr1, ref ptr2, ref len1, ref len2); /* * Write it to disk. */ byte [] rawdata = new byte[len1]; Marshal.Copy(ptr1, rawdata, 0, (int)len1); fs.Write(rawdata, 0, (int)len1); /* * Unlock the sound to allow FMOD to use it again. */ sound.unlock(ptr1, ptr2, len1, len2); fs.Close(); MessageBox.Show("Written to record.wav"); }
IEnumerator RecordCR() { int recRate = 0; int namelen = 255; System.Text.StringBuilder name = new System.Text.StringBuilder(namelen); System.Guid guid; FMOD.SPEAKERMODE speakermode; FMOD.DRIVER_STATE driverstate; result = system.getRecordDriverInfo(this.recordDeviceId, name, namelen, out guid, out recRate, out speakermode, out recChannels, out driverstate); ERRCHECK(result, "system.getRecordDriverInfo"); // compensate the input rate for the current output rate this.GetComponent <AudioSource>().pitch = ((float)(recRate * recChannels) / (float)(AudioSettings.outputSampleRate * (int)AudioSettings.speakerMode)); exinfo = new FMOD.CREATESOUNDEXINFO(); exinfo.numchannels = recChannels; exinfo.format = FMOD.SOUND_FORMAT.PCM16; exinfo.defaultfrequency = recRate; exinfo.length = (uint)(recRate * sizeof(short) * recChannels); result = system.createSound(string.Empty, FMOD.MODE.LOOP_NORMAL | FMOD.MODE.OPENUSER, ref exinfo, out sound); ERRCHECK(result, "system.createSound"); this.GetComponent <AudioSource>().Play(); result = system.recordStart(this.recordDeviceId, sound, true); ERRCHECK(result, "system.recordStart"); result = sound.getLength(out soundlength, FMOD.TIMEUNIT.PCM); ERRCHECK(result, "sound.getLength"); this.isRecording = true; if (this.OnRecordingStarted != null) { this.OnRecordingStarted.Invoke(this.gameObjectName); } for (;;) { result = system.update(); ERRCHECK(result, "system.update", false); if (this.isPaused) { yield return(null); } uint recordpos = 0; system.getRecordPosition(this.recordDeviceId, out recordpos); ERRCHECK(result, "system.getRecordPosition"); if (recordpos != lastrecordpos) { int blocklength; blocklength = (int)recordpos - (int)lastrecordpos; if (blocklength < 0) { blocklength += (int)soundlength; } /* * Lock the sound to get access to the raw data. */ result = sound.@lock((uint)(lastrecordpos * exinfo.numchannels * 2), (uint)(blocklength * exinfo.numchannels * 2), out ptr1, out ptr2, out len1, out len2); /* * exinfo.numchannels * 2 = stereo 16bit. 1 sample = 4 bytes. */ /* * Write it to output. */ if (ptr1.ToInt64() != 0 && len1 > 0) { datalength += len1; byte[] barr = new byte[len1]; Marshal.Copy(ptr1, barr, 0, (int)len1); this.AddBytesToOutputBuffer(barr); } if (ptr2.ToInt64() != 0 && len2 > 0) { datalength += len2; byte[] barr = new byte[len2]; Marshal.Copy(ptr2, barr, 0, (int)len2); this.AddBytesToOutputBuffer(barr); } /* * Unlock the sound to allow FMOD to use it again. */ result = sound.unlock(ptr1, ptr2, len1, len2); } lastrecordpos = recordpos; // print(string.Format("Record buffer pos = {0} : Record time = {1}:{2}", recordpos, datalength / exinfo.defaultfrequency / exinfo.numchannels / 2 / 60, (datalength / exinfo.defaultfrequency / exinfo.numchannels / 2) % 60)); // System.Threading.Thread.Sleep(10); yield return(null); } }