1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-13 11:29:51 +03:00

Switched recorder library to one custom made by Tomas Andersson.

Lots of small changes to both Speaker and Recorder.
This commit is contained in:
Kjell Kernen 2014-03-20 22:32:37 +01:00
parent 5a5da9da32
commit eceedefa94
16 changed files with 575 additions and 69 deletions

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Recorder. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -29,7 +29,7 @@
<ListView Name="lvSentences"
SelectionMode="Single"
MouseDoubleClick="lvSentences_MouseDoubleClick"
MouseDoubleClick="sentenceRowDblClk"
VerticalAlignment="Stretch" >
@ -55,7 +55,7 @@
<ComboBox Name="cbLanguages"
DisplayMemberPath="lName"
SelectedValuePath="sName"
SelectionChanged="cbLanguages_SelectionChanged"
SelectionChanged="switchLanguage"
Width="200" Height="23" />
</StackPanel>
@ -86,21 +86,21 @@
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,5,0,0">
<Button Content="New Sentence" Width="120" Height="32" Name="buttonAddItem" Click="buttonAddItem_Click"/>
<Button Name="btnRecord" ToolTip="Start recording" Click="btnRecord_Click" Margin="20,0,0,0" >
<Button Content="New Sentence" Width="120" Height="32" Name="buttonAddItem" Click="addSentence"/>
<Button Name="btnRecord" ToolTip="Start recording" Click="record" Margin="20,0,0,0" >
<Image Height="32" Source="/OpenTXrecorder;component/record.png"/>
</Button>
<Button Name="btnStop" ToolTip="Stop recording" Click="btnStop_Click" Margin="5,0,0,0" >
<Button Name="btnStop" ToolTip="Stop recording" Click="stop" Margin="5,0,0,0" >
<Image Height="32" Source="/OpenTXrecorder;component/stop.png" />
</Button>
<Button Name="btnPlay" ToolTip="Play Sentence" Click="btnPlay_Click" Margin="30,0,0,0" >
<Button Name="btnPlay" ToolTip="Play Sentence" Click="play" Margin="30,0,0,0" >
<Image Height="32" Source="/OpenTXrecorder;component/play.png" />
</Button>
</StackPanel>
<Separator Height="5" />
<Label Content="RECORDING" Name="lblRecording" HorizontalAlignment="Center" Foreground="Red" FontSize="24" FontWeight="Black" Visibility="Hidden" />
</StackPanel>
<Image Grid.Row="0" Grid.Column="1" Name="openTXLogo" Height="48" MouseLeftButtonDown="openTXLogo_MouseLeftButtonDown" HorizontalAlignment="Right" Cursor="Hand" Margin="0,0,0,0" Source="/OpenTXrecorder;component/recorder_logo.png" Stretch="Uniform" VerticalAlignment="Bottom" />
<Image Grid.Row="0" Grid.Column="1" Name="openTXLogo" Height="48" MouseLeftButtonDown="about" HorizontalAlignment="Right" Cursor="Hand" Margin="0,0,0,0" Source="/OpenTXrecorder;component/recorder_logo.png" Stretch="Uniform" VerticalAlignment="Bottom" />
</Grid>

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Recorder. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */
@ -26,19 +26,22 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Navigation;
using System.Runtime.InteropServices;
using WaveLib;
using System.Net;
namespace OpenTXrecorder
{
public partial class MainWindow : Window
{
[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
SentenceTables tables = new SentenceTables();
Languages languages = new Languages();
Language curLang;
Sentences sentences = new Sentences();
int added_files = 0;
Languages languages = new Languages();
Environment env;
WavFileWriter filewriter;
WaveInRecorder recorder;
byte[] tmparray;
bool isRecording = false;
public MainWindow()
@ -61,7 +64,7 @@ namespace OpenTXrecorder
languages.Add("Swedish", "se");
languages.Add("Slovak", "sk");
languages.Add("Spanish", "es");
curLang = languages[0];
env = new Environment(languages[0].sName);
cbLanguages.SelectedIndex = 0; // Note: Sets current langugage -> triggers loadlanguage()
}
@ -72,38 +75,38 @@ namespace OpenTXrecorder
try
{
system_strings = System.IO.File.ReadAllLines(@"SOUNDS\" + curLang.sName + @"\SYSTEM\system_sounds.txt");
other_strings = System.IO.File.ReadAllLines(@"SOUNDS\" + curLang.sName + @"\other_sounds.txt");
system_strings = System.IO.File.ReadAllLines(env.systemSounds());
other_strings = System.IO.File.ReadAllLines(env.otherSounds());
}
catch (IOException)
{
system_strings = tables.default_system_strings[tables.toInt(curLang.sName)];
other_strings = tables.default_other_strings[tables.toInt(curLang.sName)];
system_strings = tables.default_system_strings[tables.toInt(env.shortLanguage)];
other_strings = tables.default_other_strings[tables.toInt(env.shortLanguage)];
}
sentences.RemoveRange(0, sentences.Count);
sentences.Clear();
foreach (string str in system_strings)
sentences.Add(str, @"SOUNDS\" + curLang.sName + @"\SYSTEM\");
sentences.Add(str, env.sysDir());
sentences.Add(@";^ System Sounds ^;", "");
foreach (string str in other_strings)
sentences.Add(str, @"SOUNDS\" + curLang.sName + @"\");
sentences.Add(str, env.baseDir());
lvSentences.Items.Refresh(); // Workaround - Two way binding is better
}
private void saveLanguage()
{
System.IO.Directory.CreateDirectory(@"SOUNDS\" + curLang.sName + @"\SYSTEM");
StreamWriter sw = File.CreateText(@"SOUNDS\" + curLang.sName + @"\SYSTEM\system_sounds.txt");
System.IO.Directory.CreateDirectory(env.sysDir());
StreamWriter sw = File.CreateText(env.systemSounds());
int i;
for (i = 0; sentences[i].fileName != ""; i++)
{
sw.WriteLine(sentences[i].toRaw());
}
sw.Close();
sw = File.CreateText(@"SOUNDS\" + curLang.sName + @"\other_sounds.txt");
sw = File.CreateText(env.otherSounds());
for (i++; i < sentences.Count; i++)
{
sw.WriteLine(sentences[i].toRaw());
@ -111,15 +114,26 @@ namespace OpenTXrecorder
sw.Close();
}
private void cbLanguages_SelectionChanged(object sender, SelectionChangedEventArgs e)
private void switchLanguage(object sender, SelectionChangedEventArgs e)
{
curLang = (Language)e.AddedItems[0];
env = new Environment(((Language)e.AddedItems[0]).sName);
loadLanguage();
}
private void lvSentences_MouseDoubleClick(object sender, MouseButtonEventArgs e)
private void about(object sender, MouseButtonEventArgs e)
{
if (this.lvSentences.SelectedItems.Count < 1) return;
AboutWindow aboutWindow = new AboutWindow();
aboutWindow.ShowDialog();
}
private void sentenceRowDblClk(object sender, MouseButtonEventArgs e)
{
if (this.lvSentences.SelectedItems.Count < 1)
return;
if (isRecording)
stop(null, null);
Sentence sentence = (Sentence)this.lvSentences.SelectedItem;
if (sentence.fileExists)
@ -133,27 +147,33 @@ namespace OpenTXrecorder
}
}
private void openTXLogo_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
private void play(object sender, RoutedEventArgs e)
{
AboutWindow aboutWindow = new AboutWindow();
aboutWindow.ShowDialog();
sentenceRowDblClk(null, null);
}
private void buttonAddItem_Click(object sender, RoutedEventArgs e)
private void addSentence(object sender, RoutedEventArgs e)
{
added_files++;
sentences.Add(new Sentence("new_file_" + added_files.ToString() + ";New Description;New Voice Message", @"SOUNDS\" + curLang.sName + @"\"));
int i = 0;
string newFile;
do
{
newFile = "new_file_" + i.ToString();
i++;
}
while (env.fileExists(newFile));
sentences.Add(new Sentence(newFile + ";New Description;New Voice Message", env.baseDir()));
this.lvSentences.Items.Refresh();
this.lvSentences.SelectedIndex = this.lvSentences.Items.Count - 1;
this.lvSentences.ScrollIntoView(this.lvSentences.SelectedItem);
}
private void btnRecord_Click(object sender, RoutedEventArgs e)
private void record(object sender, RoutedEventArgs e)
{
if (this.lvSentences.SelectedItems.Count < 1) return;
if (isRecording)
btnStop_Click(sender, e);
stop(sender, e);
else
{
saveLanguage();
@ -164,30 +184,77 @@ namespace OpenTXrecorder
Directory.CreateDirectory(Path.GetDirectoryName(path)); // Create directory if it doesn't exist
System.IO.File.WriteAllText(path, ""); // Creates and flushes a file if it does not exist
mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
mciSendString("record recsound", "", 0, 0);
int samplerate = 16000;
int bits = 16; // 8 or 16
int channels = 1; // 1 or 2
filewriter = new WavFileWriter(path, samplerate, bits, channels);
WaveFormat fmt = new WaveFormat(samplerate, bits, channels);
// devicenumber, wavformat, buffersize, callback
int buffersize = 1024 * 2;
tmparray = new byte[buffersize];
recorder = new WaveInRecorder(-1, fmt, buffersize, this.DataArrived);
}
}
private void btnStop_Click(object sender, RoutedEventArgs e)
private void stop(object sender, RoutedEventArgs e)
{
if (this.lvSentences.SelectedItems.Count < 1) return;
if (!isRecording || this.lvSentences.SelectedItems.Count < 1)
return;
isRecording = false;
recorder.Close();
filewriter.Close();
int index = this.lvSentences.SelectedIndex;
lblRecording.Visibility = System.Windows.Visibility.Hidden;
isRecording = false;
Sentence sentence = (Sentence)this.lvSentences.SelectedItem;
mciSendString("save recsound " + sentence.fullPath(), "", 0, 0);
mciSendString("close recsound ", "", 0, 0);
loadLanguage(); // Called to refresh the sentence data of the current langugae
this.lvSentences.SelectedIndex = index;
}
private void btnPlay_Click(object sender, RoutedEventArgs e)
private void DataArrived(IntPtr data, int size)
{
lblRecording.Visibility = System.Windows.Visibility.Hidden;
lvSentences_MouseDoubleClick(sender, null);
if (!isRecording)
return;
Marshal.Copy(data, tmparray, 0, size);
filewriter.Write(tmparray);
}
}
public class Environment
{
public string shortLanguage { get; set; }
public string baseDir() { return @"SOUNDS\" + shortLanguage + @"\"; }
public string sysDir() { return @"SOUNDS\" + shortLanguage + @"\SYSTEM\"; }
public string otherSounds() { return baseDir() + "other_sounds.txt"; }
public string systemSounds() { return sysDir() + "system_sounds.txt"; }
public bool fileExists(string fName)
{
if (File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + baseDir() + fName + ".wav"))
return true;
if (File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + sysDir() + fName + ".wav"))
return true;
return false;
}
public Environment(string str)
{
shortLanguage = str;
}
}
/*
* Data container classes
*/
public class Languages : List<Language>
{
public void Add(string longer, string shorter)
{
this.Add(new Language { lName = longer, sName = shorter });
}
}
@ -197,21 +264,21 @@ namespace OpenTXrecorder
public string sName { get; set; }
}
public class Languages : List<Language>
public class Sentences : List<Sentence>
{
public void Add(string longer, string shorter)
public void Add(string rawString, string dirPath)
{
this.Add(new Language { lName = longer, sName = shorter });
this.Add(new Sentence(rawString, dirPath));
}
}
public class Sentence
{
public bool fileExists { get; set; }
public string fileName { get; set; }
public string description { get; set; }
public string voiceString { get; set; }
public string path { get; set; }
public bool fileExists { get; set; }
public Sentence(string rawString, string dirPath)
{
@ -234,11 +301,4 @@ namespace OpenTXrecorder
}
}
public class Sentences : List<Sentence>
{
public void Add(string rawString, string dirPath)
{
this.Add(new Sentence(rawString, dirPath));
}
}
}

View file

@ -81,6 +81,8 @@
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="sentencetables.cs" />
<Compile Include="WaveIn.cs" />
<Compile Include="WaveNative.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

101
sound/recorder/Program.cs Normal file
View file

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using WaveLib;
namespace AudioRecorder
{
class Program
{
WavFileWriter filewriter;
byte[] tmparray;
void Go()
{
int samplerate = 16000;
int bits = 16; // 8 or 16
int channels = 1; // 1 or 2
filewriter = new WavFileWriter("out.wav", samplerate, bits, channels);
WaveFormat fmt = new WaveFormat(samplerate, bits, channels);
// devicenumber, wavformat, buffersize, callback
int buffersize = 16384;
WaveInRecorder rec = new WaveInRecorder(-1, fmt, buffersize, this.DataArrived);
tmparray = new byte[buffersize];
Console.WriteLine("Recording - press Enter to end");
Console.ReadLine();
rec.Close();
filewriter.Close();
Console.WriteLine("Bye");
}
private void DataArrived(IntPtr data, int size)
{
Console.WriteLine("DataArrived {0} bytes", size);
Marshal.Copy(data, tmparray, 0, size);
filewriter.Write(tmparray);
}
static void Main(string[] args)
{
new Program().Go();
}
}
class WavFileWriter
{
BinaryWriter filewriter;
long audiobyteswritten;
public WavFileWriter(string filename, int samplerate, int bits, int channels)
{
filewriter = new BinaryWriter(File.Open(filename, FileMode.Create));
filewriter.Write((uint)0x46464952); // "RIFF"
filewriter.Write((uint)0); // chunkisize (filled in when we close)
filewriter.Write((uint)0x45564157); // "WAVE"
// subchunk1
filewriter.Write((uint)0x20746d66); // "fmt "
filewriter.Write((uint)16);
filewriter.Write((UInt16)1);
filewriter.Write((UInt16)channels);
filewriter.Write((uint)samplerate);
filewriter.Write((uint)(channels*samplerate*bits/8));
filewriter.Write((UInt16)(channels*bits/8));
filewriter.Write((UInt16)bits);
// subchunk2
filewriter.Write((uint)0x61746164); // "data"
filewriter.Write((uint)0); // chunkisize (filled in when we close)
}
public void Write(byte[] data)
{
filewriter.Write(data);
audiobyteswritten += data.Length;
}
public void Close()
{
filewriter.Seek(4, SeekOrigin.Begin);
filewriter.Write((uint)(audiobyteswritten + 36)); // 36 = total size of chunk headers
filewriter.Seek(40, SeekOrigin.Begin);
filewriter.Write((uint)audiobyteswritten);
filewriter.Close();
}
}
}

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Recorder. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

214
sound/recorder/WaveIn.cs Normal file
View file

@ -0,0 +1,214 @@
/*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with the code. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Tomas Andersson */
using System;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
namespace WaveLib
{
public delegate void BufferDoneEventHandler(IntPtr data, int size);
internal class WaveInBuffer
{
private ManualResetEvent m_RecordEvent = new ManualResetEvent(false);
private IntPtr m_WaveIn;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
}
public WaveInBuffer(IntPtr waveInHandle, int size)
{
m_WaveIn = waveInHandle;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
m_HeaderData = new byte[size];
m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
m_Header.dwBufferLength = size;
WaveInRecorder.ThrowOnError(WaveNative.waveInPrepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
}
public void Close()
{
WaveInRecorder.ThrowOnError(WaveNative.waveInUnprepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
m_HeaderDataHandle.Free();
}
public int Size
{
get { return m_Header.dwBufferLength; }
}
public IntPtr Data
{
get { return m_Header.lpData; }
}
public void Record()
{
m_RecordEvent.Reset();
WaveInRecorder.ThrowOnError(WaveNative.waveInAddBuffer(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
}
public void WaitFor()
{
m_RecordEvent.WaitOne();
}
private void OnCompleted()
{
m_RecordEvent.Set();
}
}
class WavFileWriter
{
BinaryWriter filewriter;
long audiobyteswritten;
public WavFileWriter(string filename, int samplerate, int bits, int channels)
{
filewriter = new BinaryWriter(File.Open(filename, FileMode.Create));
filewriter.Write((uint)0x46464952); // "RIFF"
filewriter.Write((uint)0); // chunkisize (filled in when we close)
filewriter.Write((uint)0x45564157); // "WAVE"
// subchunk1
filewriter.Write((uint)0x20746d66); // "fmt "
filewriter.Write((uint)16);
filewriter.Write((UInt16)1);
filewriter.Write((UInt16)channels);
filewriter.Write((uint)samplerate);
filewriter.Write((uint)(channels * samplerate * bits / 8));
filewriter.Write((UInt16)(channels * bits / 8));
filewriter.Write((UInt16)bits);
// subchunk2
filewriter.Write((uint)0x61746164); // "data"
filewriter.Write((uint)0); // chunkisize (filled in when we close)
}
public void Write(byte[] data)
{
filewriter.Write(data);
audiobyteswritten += data.Length;
}
public void Close()
{
filewriter.Seek(4, SeekOrigin.Begin);
filewriter.Write((uint)(audiobyteswritten + 36)); // 36 = total size of chunk headers
filewriter.Seek(40, SeekOrigin.Begin);
filewriter.Write((uint)audiobyteswritten);
filewriter.Close();
}
}
public class WaveInRecorder
{
private IntPtr m_WaveIn;
private WaveInBuffer buffer1, buffer2;
private WaveInBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferDoneEventHandler m_DoneProc;
private bool m_Finished;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc);
public static int DeviceCount
{
get { return WaveNative.waveInGetNumDevs(); }
}
public WaveInRecorder(int device, WaveFormat format, int bufferSize, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;
WaveInRecorder.ThrowOnError(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
buffer1 = new WaveInBuffer(m_WaveIn, bufferSize);
buffer2 = new WaveInBuffer(m_WaveIn, bufferSize);
buffer1.Record();
buffer2.Record();
m_CurrentBuffer = buffer1;
WaveInRecorder.ThrowOnError(WaveNative.waveInStart(m_WaveIn));
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
}
public void Close()
{
m_Finished = true;
WaveInRecorder.ThrowOnError(WaveNative.waveInReset(m_WaveIn));
m_Thread.Join();
m_Thread = null;
m_DoneProc = null;
buffer1.WaitFor();
buffer2.WaitFor();
buffer1.Close();
buffer2.Close();
WaveInRecorder.ThrowOnError(WaveNative.waveInClose(m_WaveIn));
m_WaveIn = IntPtr.Zero;
}
private void ThreadProc()
{
while (!m_Finished)
{
m_CurrentBuffer = (m_CurrentBuffer == buffer1) ? buffer2 : buffer1;
m_CurrentBuffer.WaitFor();
m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size);
if (m_Finished) break;
m_CurrentBuffer.Record();
}
}
public static void ThrowOnError(int err)
{
if (err != WaveNative.MMSYSERR_NOERROR) throw new Exception(err.ToString());
}
}
}

View file

@ -0,0 +1,129 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Email: ianier@hotmail.com
//
// Copyright (C) 1999-2003 Ianier Munoz. All Rights Reserved.
using System;
using System.Runtime.InteropServices;
namespace WaveLib
{
public enum WaveFormats
{
Pcm = 1,
Float = 3
}
[StructLayout(LayoutKind.Sequential)]
public class WaveFormat
{
public short wFormatTag;
public short nChannels;
public int nSamplesPerSec;
public int nAvgBytesPerSec;
public short nBlockAlign;
public short wBitsPerSample;
public short cbSize;
public WaveFormat(int rate, int bits, int channels)
{
wFormatTag = (short)WaveFormats.Pcm;
nChannels = (short)channels;
nSamplesPerSec = rate;
wBitsPerSample = (short)bits;
cbSize = 0;
nBlockAlign = (short)(channels * (bits / 8));
nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
}
}
internal class WaveNative
{
// consts
public const int MMSYSERR_NOERROR = 0; // no error
public const int MM_WOM_OPEN = 0x3BB;
public const int MM_WOM_CLOSE = 0x3BC;
public const int MM_WOM_DONE = 0x3BD;
public const int MM_WIM_OPEN = 0x3BE;
public const int MM_WIM_CLOSE = 0x3BF;
public const int MM_WIM_DATA = 0x3C0;
public const int CALLBACK_FUNCTION = 0x00030000; // dwCallback is a FARPROC
public const int TIME_MS = 0x0001; // time in milliseconds
public const int TIME_SAMPLES = 0x0002; // number of wave samples
public const int TIME_BYTES = 0x0004; // current byte offset
// callbacks
public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);
// structs
[StructLayout(LayoutKind.Sequential)] public struct WaveHdr
{
public IntPtr lpData; // pointer to locked data buffer
public int dwBufferLength; // length of data buffer
public int dwBytesRecorded; // used for input only
public IntPtr dwUser; // for client's use
public int dwFlags; // assorted flags (see defines)
public int dwLoops; // loop control counter
public IntPtr lpNext; // PWaveHdr, reserved for driver
public int reserved; // reserved for driver
}
private const string mmdll = "winmm.dll";
// WaveOut calls
[DllImport(mmdll)]
public static extern int waveOutGetNumDevs();
[DllImport(mmdll)]
public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveOutReset(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutClose(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutPause(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutRestart(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
[DllImport(mmdll)]
public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
[DllImport(mmdll)]
public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);
// WaveIn calls
[DllImport(mmdll)]
public static extern int waveInGetNumDevs();
[DllImport(mmdll)]
public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
[DllImport(mmdll)]
public static extern int waveInClose(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInReset(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStart(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStop(IntPtr hwi);
}
}

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Recorder. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Recorder. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */

View file

@ -10,7 +10,7 @@
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
* along with OpenTX Speaker. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2014 Kjell Kernen */