public bool Open(string deviceName, int samplesPerSecond, int bitsPerSample, int channels, int bufferSize, int bufferCount) { this.WaveInDeviceName = deviceName; this.SamplesPerSecond = samplesPerSecond; this.BitsPerSample = bitsPerSample; this.Channels = channels; this.BufferSize = bufferSize; this.BufferCount = bufferCount; if (OpenWaveIn()) { if (CreateWaveInHeaders()) { Win32.MMRESULT hr = Win32.waveInStart(hWaveIn); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { StartThreadRecording(); return(true); } else { return(false); } } } return(false); }
/// <summary> /// StartWaveIn /// </summary> /// <returns></returns> private bool StartWaveIn() { //Wenn WaveIn werden konnte if (OpenWaveIn()) { //Wenn alle Buffer erzeugt werden konnten if (CreateWaveInHeaders()) { //Wenn die Aufnahme gestartet werden konnte Win32.MMRESULT hr = Win32.waveInStart(hWaveIn); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { IsWaveInStarted = true; Stopped = false; //Thread starten StartThreadPlayWaveIn(); return(true); } else { //Fehler beim Starten return(false); } } } //WaveIn konnte nicht geöffnet werden return(false); }
/// <summary> /// EndPause /// </summary> /// <returns></returns> public bool EndPause() { try { lock (Locker) { //Wenn geöffnet if (Opened) { //Wenn pausiert if (IsPaused) { //Pausieren Win32.MMRESULT hr = Win32.waveOutRestart(hWaveOut); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { //Speichern IsPaused = false; AutoResetEventDataPlayed.Set(); return(true); } } } return(false); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("EndPause | {0}", ex.Message)); return(false); } }
/// <summary> /// CreateWaveOutHeaders /// </summary> /// <returns></returns> private bool CreateWaveOutHeaders() { //Buffer anlegen WaveOutHeaders = new Win32.WAVEHDR *[BufferCount]; int createdHeaders = 0; //Für jeden Buffer for (int i = 0; i < BufferCount; i++) { //Header allokieren WaveOutHeaders[i] = (Win32.WAVEHDR *)Marshal.AllocHGlobal(sizeof(Win32.WAVEHDR)); //Header setzen WaveOutHeaders[i]->dwLoops = 0; WaveOutHeaders[i]->dwUser = IntPtr.Zero; WaveOutHeaders[i]->lpNext = IntPtr.Zero; WaveOutHeaders[i]->reserved = IntPtr.Zero; WaveOutHeaders[i]->lpData = Marshal.AllocHGlobal(BufferLength); WaveOutHeaders[i]->dwBufferLength = (uint)BufferLength; WaveOutHeaders[i]->dwBytesRecorded = 0; WaveOutHeaders[i]->dwFlags = 0; //Wenn der Buffer vorbereitet werden konnte Win32.MMRESULT hr = Win32.waveOutPrepareHeader(hWaveOut, WaveOutHeaders[i], sizeof(Win32.WAVEHDR)); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { createdHeaders++; } } //Fertig return(createdHeaders == BufferCount); }
public bool PlayData(byte[] data) { int index = GetNextFreeWaveOutHeaderIndex(); if (index != -1) { if (WaveOutHeaders[index]->dwBufferLength != data.Length) { Marshal.FreeHGlobal(WaveOutHeaders[index]->lpData); WaveOutHeaders[index]->lpData = Marshal.AllocHGlobal(data.Length); WaveOutHeaders[index]->dwBufferLength = (uint)data.Length; } WaveOutHeaders[index]->dwBufferLength = (uint)data.Length; WaveOutHeaders[index]->dwUser = (IntPtr)index; Marshal.Copy(data, 0, WaveOutHeaders[index]->lpData, data.Length); Win32.MMRESULT hr = Win32.waveOutWrite(hWaveOut, WaveOutHeaders[index], sizeof(Win32.WAVEHDR)); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// CreateWaveInHeaders /// </summary> /// <param name="count"></param> /// <param name="bufferSize"></param> /// <returns></returns> private bool CreateWaveInHeaders() { WaveInHeaders = new Win32.WAVEHDR *[BufferCount]; int createdHeaders = 0; for (int i = 0; i < BufferCount; i++) { WaveInHeaders[i] = (Win32.WAVEHDR *)Marshal.AllocHGlobal(sizeof(Win32.WAVEHDR)); WaveInHeaders[i]->dwLoops = 0; WaveInHeaders[i]->dwUser = IntPtr.Zero; WaveInHeaders[i]->lpNext = IntPtr.Zero; WaveInHeaders[i]->reserved = IntPtr.Zero; WaveInHeaders[i]->lpData = Marshal.AllocHGlobal(BufferSize); WaveInHeaders[i]->dwBufferLength = (uint)BufferSize; WaveInHeaders[i]->dwBytesRecorded = 0; WaveInHeaders[i]->dwFlags = 0; Win32.MMRESULT hr = Win32.waveInPrepareHeader(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { if (i == 0) { hr = Win32.waveInAddBuffer(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); } createdHeaders++; } } return(createdHeaders == BufferCount); }
/// <summary> /// CloseWaveIn /// </summary> /// <returns></returns> private void CloseWaveIn() { //Als manuell beendet setzen Stopped = true; IsThreadPlayWaveInRunning = false; AutoResetEventDataRecorded.Set(); //WaveIn stoppen Win32.MMRESULT hResult = Win32.waveInStop(hWaveIn); //Buffer als abgearbeitet setzen int resetCount = 0; while (IsAnyWaveInHeaderInState(Win32.WaveHdrFlags.WHDR_INQUEUE) & resetCount < 20) { Win32.MMRESULT hr = Win32.waveInReset(hWaveIn); System.Threading.Thread.Sleep(50); resetCount++; } //Header Handles freigeben (vor waveInClose) FreeWaveInHeaders(); //Schliessen while (Win32.waveInClose(hWaveIn) == Win32.MMRESULT.WAVERR_STILLPLAYING) { System.Threading.Thread.Sleep(50); } }
/// <summary> /// FreeWaveInHeaders /// </summary> private void FreeWaveInHeaders() { if (WaveInHeaders != null) { for (int i = 0; i < WaveInHeaders.Length; i++) { Win32.MMRESULT hr = Win32.waveInUnprepareHeader(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); int count = 0; while (count <= 100 && (WaveInHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == Win32.WaveHdrFlags.WHDR_INQUEUE) { System.Threading.Thread.Sleep(20); count++; } if ((WaveInHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) != Win32.WaveHdrFlags.WHDR_INQUEUE) { if (WaveInHeaders[i]->lpData != IntPtr.Zero) { Marshal.FreeHGlobal(WaveInHeaders[i]->lpData); WaveInHeaders[i]->lpData = IntPtr.Zero; } } } } }
/// <summary> /// Start /// </summary> /// <param name="waveInDeviceName"></param> /// <param name="waveOutDeviceName"></param> /// <param name="samplesPerSecond"></param> /// <param name="bitsPerSample"></param> /// <param name="channels"></param> /// <returns></returns> public bool Start(string waveInDeviceName, int samplesPerSecond, int bitsPerSample, int channels, int bufferCount, int bufferSize) { try { lock (Locker) { //Wenn nicht schon gestartet if (Started == false) { //Daten übernehmen WaveInDeviceName = waveInDeviceName; SamplesPerSecond = samplesPerSecond; BitsPerSample = bitsPerSample; Channels = channels; BufferCount = bufferCount; BufferSize = bufferSize; //Wenn WaveIn geöffnet werden konnte if (OpenWaveIn()) { //Wenn alle Buffer erzeugt werden konnten if (CreateWaveInHeaders()) { //Wenn die Aufnahme gestartet werden konnte Win32.MMRESULT hr = Win32.waveInStart(hWaveIn); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { IsWaveInStarted = true; //Thread starten StartThreadRecording(); Stopped = false; return(true); } else { //Fehler beim Starten return(false); } } } } //Repeater läuft bereits return(false); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Start | {0}", ex.Message)); return(false); } }
/// <summary> /// CloseWaveOut /// </summary> /// <returns></returns> private void CloseWaveOut() { //Anhalten IsWaveOutOpened = false; Win32.MMRESULT hr = Win32.waveOutReset(hWaveOut); //Warten bis alles abgespielt while (IsAnyWaveOutHeaderInState(Win32.WaveHdrFlags.WHDR_INQUEUE)) { System.Threading.Thread.Sleep(50); } //Header Handles freigeben FreeWaveOutHeaders(); //Schliessen hr = Win32.waveOutClose(hWaveOut); }
public void Stop() { Win32.MMRESULT hr = Win32.waveInStop(hWaveIn); int resetCount = 0; while (IsAnyWaveInHeaderInState(Win32.WaveHdrFlags.WHDR_INQUEUE) & resetCount < 20) { hr = Win32.waveInReset(hWaveIn); System.Threading.Thread.Sleep(50); resetCount++; } FreeWaveInHeaders(); hr = Win32.waveInClose(hWaveIn); AutoResetEventDataRecorded.Set(); }
/// <summary> /// CloseWaveIn /// </summary> /// <returns></returns> private void CloseWaveIn() { //Buffer als abgearbeitet setzen Win32.MMRESULT hr = Win32.waveInStop(hWaveIn); int resetCount = 0; while (IsAnyWaveInHeaderInState(Win32.WaveHdrFlags.WHDR_INQUEUE) & resetCount < 20) { hr = Win32.waveInReset(hWaveIn); System.Threading.Thread.Sleep(50); resetCount++; } //Header Handles freigeben (vor waveInClose) FreeWaveInHeaders(); //Schliessen hr = Win32.waveInClose(hWaveIn); }
/// <summary> /// StartWaveIn /// </summary> /// <returns></returns> private bool OpenWaveIn() { Win32.WAVEFORMATEX waveFormatEx = new Win32.WAVEFORMATEX(); waveFormatEx.wFormatTag = (ushort)Win32.WaveFormatFlags.WAVE_FORMAT_PCM; waveFormatEx.nChannels = (ushort)Channels; waveFormatEx.nSamplesPerSec = (ushort)SamplesPerSecond; waveFormatEx.wBitsPerSample = (ushort)BitsPerSample; waveFormatEx.nBlockAlign = (ushort)((waveFormatEx.wBitsPerSample * waveFormatEx.nChannels) >> 3); waveFormatEx.nAvgBytesPerSec = (uint)(waveFormatEx.nBlockAlign * waveFormatEx.nSamplesPerSec); int deviceId = WinSound.GetWaveInDeviceIdByName(WaveInDeviceName); Win32.MMRESULT hr = Win32.waveInOpen(ref hWaveIn, deviceId, ref waveFormatEx, delegateWaveInProc, 0, (int)Win32.WaveProcFlags.CALLBACK_FUNCTION); if (hWaveIn == IntPtr.Zero) { return(false); } GCHandle.Alloc(hWaveIn, GCHandleType.Pinned); return(true); }
/// <summary> /// FreeWaveInHeaders /// </summary> private void FreeWaveOutHeaders() { try { if (WaveOutHeaders != null) { for (int i = 0; i < WaveOutHeaders.Length; i++) { //Handles freigeben Win32.MMRESULT hr = Win32.waveOutUnprepareHeader(hWaveOut, WaveOutHeaders[i], sizeof(Win32.WAVEHDR)); //Warten bis fertig abgespielt int count = 0; while (count <= 100 && (WaveOutHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == Win32.WaveHdrFlags.WHDR_INQUEUE) { System.Threading.Thread.Sleep(20); count++; } //Wenn Daten abgespielt if ((WaveOutHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) != Win32.WaveHdrFlags.WHDR_INQUEUE) { //Daten freigeben if (WaveOutHeaders[i]->lpData != IntPtr.Zero) { Marshal.FreeHGlobal(WaveOutHeaders[i]->lpData); WaveOutHeaders[i]->lpData = IntPtr.Zero; } } } } } catch (Exception ex) { System.Diagnostics.Debug.Write(ex.Message); } }
/// <summary> /// OnThreadRecording /// </summary> private void OnThreadRecording() { while (true) { AutoResetEventDataRecorded.WaitOne(); if (CurrentRecordedHeader->dwBytesRecorded > 0) { Byte[] bytes = new Byte[CurrentRecordedHeader->dwBytesRecorded]; Marshal.Copy(CurrentRecordedHeader->lpData, bytes, 0, (int)CurrentRecordedHeader->dwBytesRecorded); DataRecorded?.Invoke(bytes); for (int i = 0; i < WaveInHeaders.Length; i++) { if ((WaveInHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == 0) { Win32.MMRESULT hr = Win32.waveInAddBuffer(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); } } } } }
/// <summary> /// OpenWaveOuz /// </summary> /// <returns></returns> private bool OpenWaveOut() { if (hWaveOut == IntPtr.Zero) { //Wenn nicht schon offen if (IsWaveOutOpened == false) { //Format bestimmen Win32.WAVEFORMATEX waveFormatEx = new Win32.WAVEFORMATEX(); waveFormatEx.wFormatTag = (ushort)Win32.WaveFormatFlags.WAVE_FORMAT_PCM; waveFormatEx.nChannels = (ushort)Channels; waveFormatEx.nSamplesPerSec = (ushort)SamplesPerSecond; waveFormatEx.wBitsPerSample = (ushort)BitsPerSample; waveFormatEx.nBlockAlign = (ushort)((waveFormatEx.wBitsPerSample * waveFormatEx.nChannels) >> 3); waveFormatEx.nAvgBytesPerSec = (uint)(waveFormatEx.nBlockAlign * waveFormatEx.nSamplesPerSec); //WaveOut Gerät ermitteln int deviceId = WinSound.GetWaveOutDeviceIdByName(WaveOutDeviceName); //WaveIn Gerät öffnen Win32.MMRESULT hr = Win32.waveOutOpen(ref hWaveOut, deviceId, ref waveFormatEx, delegateWaveOutProc, 0, (int)Win32.WaveProcFlags.CALLBACK_FUNCTION); //Wenn nicht erfolgreich if (hr != Win32.MMRESULT.MMSYSERR_NOERROR) { IsWaveOutOpened = false; return(false); } //Handle sperren GCHandle.Alloc(hWaveOut, GCHandleType.Pinned); } } IsWaveOutOpened = true; return(true); }
/// <summary> /// PlayBytes. Bytes in gleich grosse Stücke teilen und einzeln abspielen /// </summary> /// <param name="bytes"></param> /// <returns></returns> private bool PlayBytes(Byte[] bytes) { if (bytes.Length > 0) { //Grösse der Bytestücke int byteSize = bytes.Length / BufferCount; int currentPos = 0; //Für jeden möglichen Buffer for (int count = 0; count < BufferCount; count++) { //Nächsten freien Buffer ermitteln int index = GetNextFreeWaveOutHeaderIndex(); if (index != -1) { try { //Teilstück kopieren Byte[] partByte = new Byte[byteSize]; Array.Copy(bytes, currentPos, partByte, 0, byteSize); currentPos += byteSize; //Wenn unterschiedliche Datengrösse if (WaveOutHeaders[index]->dwBufferLength != partByte.Length) { //Datenspeicher neu anlegen Marshal.FreeHGlobal(WaveOutHeaders[index]->lpData); WaveOutHeaders[index]->lpData = Marshal.AllocHGlobal(partByte.Length); WaveOutHeaders[index]->dwBufferLength = (uint)partByte.Length; } //Daten kopieren WaveOutHeaders[index]->dwUser = (IntPtr)index; Marshal.Copy(partByte, 0, WaveOutHeaders[index]->lpData, partByte.Length); } catch (Exception ex) { //Fehler beim Kopieren System.Diagnostics.Debug.WriteLine(String.Format("CopyBytesToFreeWaveOutHeaders() | {0}", ex.Message)); AutoResetEventDataPlayed.Set(); return(false); } //Wenn noch geöffnet if (hWaveOut != null) { //Abspielen Win32.MMRESULT hr = Win32.waveOutWrite(hWaveOut, WaveOutHeaders[index], sizeof(Win32.WAVEHDR)); if (hr != Win32.MMRESULT.MMSYSERR_NOERROR) { //Fehler beim Abspielen AutoResetEventDataPlayed.Set(); return(false); } } else { //WaveOut ungültig return(false); } } else { //Nicht genügend freie Buffer vorhanden return(false); } } return(true); } //Keine Daten vorhanden return(false); }
/// <summary> /// MMRESULT 値から Win32Exception オブジェクトを生成する。 /// </summary> /// <param name="result">MMRESULT 値。</param> internal Win32Exception(Win32.MMRESULT result) : base(result.ToString()) { }
/// <summary> /// OnThreadRecording /// </summary> private void OnThreadPlayWaveIn() { while (IsThreadPlayWaveInRunning && !Stopped) { //Warten bis Aufnahme beendet AutoResetEventDataRecorded.WaitOne(); try { if (IsThreadPlayWaveInRunning && IsDataIncomming && IsWaveOutOpened && IsMute == false) { //Nächsten freien Abspielbuffer ermitteln for (int i = 0; i < WaveOutHeaders.Length; i++) { if ((WaveOutHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == 0) { try { //Daten in Abspielbuffer kopieren Marshal.Copy(CurrentRecordedHeader->lpData, CopyDataBuffer, 0, CopyDataBuffer.Length); Marshal.Copy(CopyDataBuffer, 0, WaveOutHeaders[i]->lpData, CopyDataBuffer.Length); //Daten Abspielen Win32.MMRESULT hr = Win32.waveOutWrite(hWaveOut, WaveOutHeaders[i], sizeof(Win32.WAVEHDR)); break; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } } } if (IsThreadPlayWaveInRunning && !Stopped) { //Weiter Aufnehmen for (int i = 0; i < WaveInHeaders.Length; i++) { if ((WaveInHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == 0) { Win32.MMRESULT hr = Win32.waveInAddBuffer(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); } } } ////Playing //StringBuilder play = new StringBuilder(); //play.AppendLine(""); //play.AppendLine("Playing:"); //for (int i = 0; i < WaveOutHeaders.Length; i++) //{ // play.AppendLine(String.Format("{0} {1}", i, WinSound.FlagToString(WaveOutHeaders[i]->dwFlags))); //} //play.AppendLine(""); //System.Diagnostics.Debug.WriteLine(play.ToString()); ////Recording //StringBuilder rec = new StringBuilder(); //rec.AppendLine(""); //rec.AppendLine("Recording:"); //for (int i = 0; i < WaveInHeaders.Length; i++) //{ // rec.AppendLine(String.Format("{0} {1}", i, WinSound.FlagToString(WaveInHeaders[i]->dwFlags))); //} //rec.AppendLine(""); //System.Diagnostics.Debug.WriteLine(rec.ToString()); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } //Variablen setzen IsWaveInStarted = false; IsThreadPlayWaveInRunning = false; AutoResetEventThreadPlayWaveInEnd.Set(); //Ereignis aussenden if (RepeaterStopped != null) { try { RepeaterStopped(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Repeater Stopped | {0}", ex.Message)); } } }
/// <summary> /// OnThreadRecording /// </summary> private void OnThreadRecording() { while (Started && !Stopped) { //Warten bis Aufnahme beendet AutoResetEventDataRecorded.WaitOne(); try { //Wenn aktiv if (Started && !Stopped) { //Wenn Daten vorhanden if (CurrentRecordedHeader->dwBytesRecorded > 0) { //Wenn Daten abgefragt werden if (DataRecorded != null && IsDataIncomming) { try { //Daten kopieren Byte[] bytes = new Byte[CurrentRecordedHeader->dwBytesRecorded]; Marshal.Copy(CurrentRecordedHeader->lpData, bytes, 0, (int)CurrentRecordedHeader->dwBytesRecorded); //Event abschicken DataRecorded(bytes); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Recorder.cs | OnThreadRecording() | {0}", ex.Message)); } } //Weiter Aufnehmen for (int i = 0; i < WaveInHeaders.Length; i++) { if ((WaveInHeaders[i]->dwFlags & Win32.WaveHdrFlags.WHDR_INQUEUE) == 0) { Win32.MMRESULT hr = Win32.waveInAddBuffer(hWaveIn, WaveInHeaders[i], sizeof(Win32.WAVEHDR)); } } } } ////Recording //StringBuilder rec = new StringBuilder(); //rec.AppendLine(""); //rec.AppendLine("Recording:"); //for (int i = 0; i < WaveInHeaders.Length; i++) //{ // rec.AppendLine(String.Format("{0} {1}", i, WinSound.FlagToString(WaveInHeaders[i].dwFlags))); //} //rec.AppendLine(""); //System.Diagnostics.Debug.WriteLine(rec.ToString()); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } lock (Locker) { //Variablen setzen IsWaveInStarted = false; IsThreadRecordingRunning = false; } //Ereignis aussenden if (RecordingStopped != null) { try { RecordingStopped(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("Recording Stopped | {0}", ex.Message)); } } }
/// <summary> /// PlayData /// </summary> /// <param name="datas"></param> /// <param name="isBlocking"></param> /// <returns></returns> public bool PlayData(Byte[] datas, bool isBlocking) { try { if (Opened) { int index = GetNextFreeWaveOutHeaderIndex(); if (index != -1) { //Werte übernehmen this.IsBlocking = isBlocking; //Wenn unterschiedliche Datengrösse if (WaveOutHeaders[index]->dwBufferLength != datas.Length) { //Datenspeicher neu anlegen Marshal.FreeHGlobal(WaveOutHeaders[index]->lpData); WaveOutHeaders[index]->lpData = Marshal.AllocHGlobal(datas.Length); WaveOutHeaders[index]->dwBufferLength = (uint)datas.Length; } //Daten kopieren WaveOutHeaders[index]->dwBufferLength = (uint)datas.Length; WaveOutHeaders[index]->dwUser = (IntPtr)index; Marshal.Copy(datas, 0, WaveOutHeaders[index]->lpData, datas.Length); //Abspielen this.IsStarted = true; Win32.MMRESULT hr = Win32.waveOutWrite(hWaveOut, WaveOutHeaders[index], sizeof(Win32.WAVEHDR)); if (hr == Win32.MMRESULT.MMSYSERR_NOERROR) { //Wenn blockierend if (isBlocking) { AutoResetEventDataPlayed.WaitOne(); AutoResetEventDataPlayed.Set(); } return(true); } else { //Fehler beim Abspielen AutoResetEventDataPlayed.Set(); return(false); } } else { //Kein freier Ausgabebuffer vorhanden System.Diagnostics.Debug.WriteLine(String.Format("No free WaveOut Buffer found | {0}", DateTime.Now.ToLongTimeString())); return(false); } } else { //Nicht geöffnet return(false); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(String.Format("PlayData | {0}", ex.Message)); return(false); } }