using System; using System.Runtime.InteropServices; using System.Security; namespace SFML { namespace Audio { //////////////////////////////////////////////////////////// /// /// SoundRecorder is an interface for capturing sound data, /// it is meant to be used as a base class /// //////////////////////////////////////////////////////////// public abstract class SoundRecorder : ObjectBase { //////////////////////////////////////////////////////////// /// /// Default constructor /// //////////////////////////////////////////////////////////// public SoundRecorder() : base(IntPtr.Zero) { myStartCallback = new StartCallback(OnStart); myProcessCallback = new ProcessCallback(ProcessSamples); myStopCallback = new StopCallback(OnStop); SetThis(sfSoundRecorder_Create(myStartCallback, myProcessCallback, myStopCallback, IntPtr.Zero)); } //////////////////////////////////////////////////////////// /// /// Start the capture using default sample rate (44100 Hz) /// Warning : only one capture can happen at the same time /// //////////////////////////////////////////////////////////// public void Start() { Start(44100); } //////////////////////////////////////////////////////////// /// /// Start the capture. /// Warning : only one capture can happen at the same time /// /// Sound frequency; the more samples, the higher the quality (44100 by default = CD quality) //////////////////////////////////////////////////////////// public void Start(uint sampleRate) { sfSoundRecorder_Start(This, sampleRate); } //////////////////////////////////////////////////////////// /// /// Stop the capture /// //////////////////////////////////////////////////////////// public void Stop() { sfSoundRecorder_Stop(This); } //////////////////////////////////////////////////////////// /// /// Sample rate of the recorder, in samples per second /// //////////////////////////////////////////////////////////// public uint SampleRate { get {return sfSoundRecorder_GetSampleRate(This);} } //////////////////////////////////////////////////////////// /// /// Tell if the system supports sound capture. /// If not, this class won't be usable /// //////////////////////////////////////////////////////////// public static bool CanCapture { get {return sfSoundRecorder_CanCapture();} } //////////////////////////////////////////////////////////// /// /// Called when a new capture starts /// /// False to abort recording audio data, true to continue //////////////////////////////////////////////////////////// protected virtual bool OnStart() { // Does nothing by default return true; } //////////////////////////////////////////////////////////// /// /// Process a new chunk of recorded samples /// /// Array of samples to process /// False to stop recording audio data, true to continue //////////////////////////////////////////////////////////// protected abstract bool OnProcessSamples(short[] samples); //////////////////////////////////////////////////////////// /// /// Called when the current capture stops /// //////////////////////////////////////////////////////////// protected virtual void OnStop() { // Does nothing by default } //////////////////////////////////////////////////////////// /// /// Handle the destruction of the object /// /// Is the GC disposing the object, or is it an explicit call ? //////////////////////////////////////////////////////////// protected override void Destroy(bool disposing) { sfSoundRecorder_Destroy(This); } //////////////////////////////////////////////////////////// /// /// Function called directly by the C library ; convert /// arguments and forward them to the internal virtual function /// /// Pointer to the array of samples /// Number of samples in the array /// User data -- unused /// False to stop recording audio data, true to continue //////////////////////////////////////////////////////////// private bool ProcessSamples(IntPtr samples, uint nbSamples, IntPtr userData) { short[] samplesArray = new short[nbSamples]; Marshal.Copy(samples, samplesArray, 0, samplesArray.Length); return OnProcessSamples(samplesArray); } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool StartCallback(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool ProcessCallback(IntPtr samples, uint nbSamples, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void StopCallback(); private StartCallback myStartCallback; private ProcessCallback myProcessCallback; private StopCallback myStopCallback; #region Imports [DllImport("csfml-audio")] static extern IntPtr sfSoundRecorder_Create(StartCallback OnStart, ProcessCallback OnProcess, StopCallback OnStop, IntPtr UserData); [DllImport("csfml-audio")] static extern void sfSoundRecorder_Destroy(IntPtr SoundRecorder); [DllImport("csfml-audio")] static extern void sfSoundRecorder_Start(IntPtr SoundRecorder, uint SampleRate); [DllImport("csfml-audio")] static extern void sfSoundRecorder_Stop(IntPtr SoundRecorder); [DllImport("csfml-audio")] static extern uint sfSoundRecorder_GetSampleRate(IntPtr SoundRecorder); [DllImport("csfml-audio")] static extern bool sfSoundRecorder_CanCapture(); #endregion } } }