Added Parrot capture & playback sample.

This commit is contained in:
the_fiddler 2009-07-19 20:57:17 +00:00
parent ce2a024c14
commit a9b59d4021
3 changed files with 653 additions and 0 deletions

View file

@ -0,0 +1,283 @@
namespace Examples
{
partial class Parrot
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.comboBox_RecorderSelection = new System.Windows.Forms.ComboBox();
this.groupBox_RecorderParameters = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.numericUpDown_PlaybackGain = new System.Windows.Forms.NumericUpDown();
this.label_MONO16BIT = new System.Windows.Forms.Label();
this.label_RINGBUFFER = new System.Windows.Forms.Label();
this.label_FREQUENCY = new System.Windows.Forms.Label();
this.numericUpDown_BufferLength = new System.Windows.Forms.NumericUpDown();
this.numericUpDown_Frequency = new System.Windows.Forms.NumericUpDown();
this.groupBox_RecordingControls = new System.Windows.Forms.GroupBox();
this.label_SamplesConsumed = new System.Windows.Forms.Label();
this.button_Start = new System.Windows.Forms.Button();
this.timer_GetSamples = new System.Windows.Forms.Timer(this.components);
this.groupBox_RecorderParameters.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_PlaybackGain)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_BufferLength)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_Frequency)).BeginInit();
this.groupBox_RecordingControls.SuspendLayout();
this.SuspendLayout();
//
// comboBox_RecorderSelection
//
this.comboBox_RecorderSelection.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.comboBox_RecorderSelection.FormattingEnabled = true;
this.comboBox_RecorderSelection.Location = new System.Drawing.Point(6, 19);
this.comboBox_RecorderSelection.Name = "comboBox_RecorderSelection";
this.comboBox_RecorderSelection.Size = new System.Drawing.Size(216, 21);
this.comboBox_RecorderSelection.TabIndex = 0;
//
// groupBox_RecorderParameters
//
this.groupBox_RecorderParameters.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox_RecorderParameters.Controls.Add(this.label2);
this.groupBox_RecorderParameters.Controls.Add(this.label1);
this.groupBox_RecorderParameters.Controls.Add(this.numericUpDown_PlaybackGain);
this.groupBox_RecorderParameters.Controls.Add(this.label_MONO16BIT);
this.groupBox_RecorderParameters.Controls.Add(this.label_RINGBUFFER);
this.groupBox_RecorderParameters.Controls.Add(this.label_FREQUENCY);
this.groupBox_RecorderParameters.Controls.Add(this.numericUpDown_BufferLength);
this.groupBox_RecorderParameters.Controls.Add(this.numericUpDown_Frequency);
this.groupBox_RecorderParameters.Controls.Add(this.comboBox_RecorderSelection);
this.groupBox_RecorderParameters.Location = new System.Drawing.Point(12, 12);
this.groupBox_RecorderParameters.Name = "groupBox_RecorderParameters";
this.groupBox_RecorderParameters.Size = new System.Drawing.Size(228, 168);
this.groupBox_RecorderParameters.TabIndex = 2;
this.groupBox_RecorderParameters.TabStop = false;
this.groupBox_RecorderParameters.Text = "Recording Device Setup";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(6, 132);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(74, 13);
this.label2.TabIndex = 105;
this.label2.Text = "Sample format";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(6, 102);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(96, 13);
this.label1.TabIndex = 104;
this.label1.Text = "Playback gain (dB)";
//
// numericUpDown_PlaybackGain
//
this.numericUpDown_PlaybackGain.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.numericUpDown_PlaybackGain.Location = new System.Drawing.Point(145, 100);
this.numericUpDown_PlaybackGain.Maximum = new decimal(new int[] {
64,
0,
0,
0});
this.numericUpDown_PlaybackGain.Minimum = new decimal(new int[] {
1,
0,
0,
65536});
this.numericUpDown_PlaybackGain.Name = "numericUpDown_PlaybackGain";
this.numericUpDown_PlaybackGain.Size = new System.Drawing.Size(76, 20);
this.numericUpDown_PlaybackGain.TabIndex = 103;
this.numericUpDown_PlaybackGain.ThousandsSeparator = true;
this.numericUpDown_PlaybackGain.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// label_MONO16BIT
//
this.label_MONO16BIT.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label_MONO16BIT.AutoSize = true;
this.label_MONO16BIT.Location = new System.Drawing.Point(142, 132);
this.label_MONO16BIT.Name = "label_MONO16BIT";
this.label_MONO16BIT.Size = new System.Drawing.Size(64, 13);
this.label_MONO16BIT.TabIndex = 102;
this.label_MONO16BIT.Text = "Mono 16 Bit";
//
// label_RINGBUFFER
//
this.label_RINGBUFFER.AutoSize = true;
this.label_RINGBUFFER.Location = new System.Drawing.Point(6, 76);
this.label_RINGBUFFER.Name = "label_RINGBUFFER";
this.label_RINGBUFFER.Size = new System.Drawing.Size(89, 13);
this.label_RINGBUFFER.TabIndex = 101;
this.label_RINGBUFFER.Text = "Buffer length (ms)";
//
// label_FREQUENCY
//
this.label_FREQUENCY.AutoSize = true;
this.label_FREQUENCY.Location = new System.Drawing.Point(6, 50);
this.label_FREQUENCY.Name = "label_FREQUENCY";
this.label_FREQUENCY.Size = new System.Drawing.Size(85, 13);
this.label_FREQUENCY.TabIndex = 100;
this.label_FREQUENCY.Text = "Sample rate (Hz)";
//
// numericUpDown_BufferLength
//
this.numericUpDown_BufferLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.numericUpDown_BufferLength.Location = new System.Drawing.Point(145, 74);
this.numericUpDown_BufferLength.Maximum = new decimal(new int[] {
1000,
0,
0,
0});
this.numericUpDown_BufferLength.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numericUpDown_BufferLength.Name = "numericUpDown_BufferLength";
this.numericUpDown_BufferLength.Size = new System.Drawing.Size(76, 20);
this.numericUpDown_BufferLength.TabIndex = 2;
this.numericUpDown_BufferLength.ThousandsSeparator = true;
this.numericUpDown_BufferLength.Value = new decimal(new int[] {
50,
0,
0,
0});
//
// numericUpDown_Frequency
//
this.numericUpDown_Frequency.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.numericUpDown_Frequency.Location = new System.Drawing.Point(145, 48);
this.numericUpDown_Frequency.Maximum = new decimal(new int[] {
100000,
0,
0,
0});
this.numericUpDown_Frequency.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.numericUpDown_Frequency.Name = "numericUpDown_Frequency";
this.numericUpDown_Frequency.Size = new System.Drawing.Size(76, 20);
this.numericUpDown_Frequency.TabIndex = 1;
this.numericUpDown_Frequency.ThousandsSeparator = true;
this.numericUpDown_Frequency.Value = new decimal(new int[] {
16000,
0,
0,
0});
//
// groupBox_RecordingControls
//
this.groupBox_RecordingControls.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox_RecordingControls.Controls.Add(this.label_SamplesConsumed);
this.groupBox_RecordingControls.Controls.Add(this.button_Start);
this.groupBox_RecordingControls.Location = new System.Drawing.Point(12, 186);
this.groupBox_RecordingControls.Name = "groupBox_RecordingControls";
this.groupBox_RecordingControls.Size = new System.Drawing.Size(228, 78);
this.groupBox_RecordingControls.TabIndex = 3;
this.groupBox_RecordingControls.TabStop = false;
this.groupBox_RecordingControls.Text = "Talk to the parrot";
//
// label_SamplesConsumed
//
this.label_SamplesConsumed.AutoSize = true;
this.label_SamplesConsumed.Location = new System.Drawing.Point(6, 52);
this.label_SamplesConsumed.Name = "label_SamplesConsumed";
this.label_SamplesConsumed.Size = new System.Drawing.Size(108, 13);
this.label_SamplesConsumed.TabIndex = 103;
this.label_SamplesConsumed.Text = "Samples consumed: -";
//
// button_Start
//
this.button_Start.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.button_Start.Location = new System.Drawing.Point(35, 19);
this.button_Start.Name = "button_Start";
this.button_Start.Size = new System.Drawing.Size(159, 24);
this.button_Start.TabIndex = 3;
this.button_Start.Text = "Start recording";
this.button_Start.UseVisualStyleBackColor = true;
this.button_Start.Click += new System.EventHandler(this.button_Start_Click);
//
// timer_GetSamples
//
this.timer_GetSamples.Tick += new System.EventHandler(this.timer_UpdateSamples_Tick);
//
// Parrot
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(252, 276);
this.Controls.Add(this.groupBox_RecordingControls);
this.Controls.Add(this.groupBox_RecorderParameters);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "Parrot";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "OpenAL Parrot";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Parrot_FormClosing);
this.groupBox_RecorderParameters.ResumeLayout(false);
this.groupBox_RecorderParameters.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_PlaybackGain)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_BufferLength)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown_Frequency)).EndInit();
this.groupBox_RecordingControls.ResumeLayout(false);
this.groupBox_RecordingControls.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox_RecorderSelection;
private System.Windows.Forms.GroupBox groupBox_RecorderParameters;
private System.Windows.Forms.Label label_RINGBUFFER;
private System.Windows.Forms.Label label_FREQUENCY;
private System.Windows.Forms.NumericUpDown numericUpDown_BufferLength;
private System.Windows.Forms.NumericUpDown numericUpDown_Frequency;
private System.Windows.Forms.GroupBox groupBox_RecordingControls;
private System.Windows.Forms.Label label_SamplesConsumed;
private System.Windows.Forms.Button button_Start;
private System.Windows.Forms.Label label_MONO16BIT;
private System.Windows.Forms.Timer timer_GetSamples;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numericUpDown_PlaybackGain;
private System.Windows.Forms.Label label2;
}
}

View file

@ -0,0 +1,238 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2009 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using OpenTK.Audio;
using OpenTK;
namespace Examples
{
[Example("Parrot Audio Capture", ExampleCategory.OpenAL, "1.1", Documentation = "Parrot")]
public partial class Parrot : Form
{
#region Fields
AudioContext audio_context;
AudioCapture audio_capture;
int src;
short[] buffer = new short[512];
const byte SampleToByte = 2;
#endregion
#region Constructors
public Parrot()
{
InitializeComponent();
this.Text = "OpenAL Parrot (" + (IntPtr.Size == 4 ? "x86" : "x64") + ")";
// Add available capture devices to the combo box.
IList<string> recorders = AudioCapture.AvailableDevices;
for (int i = 0; i < recorders.Count; i++)
{
if (!String.IsNullOrEmpty(recorders[i]))
comboBox_RecorderSelection.Items.Add(recorders[i]);
}
if (comboBox_RecorderSelection.Items.Count > 0)
comboBox_RecorderSelection.SelectedIndex = 0;
}
#endregion
#region Events
private void button_Start_Click(object sender, EventArgs e)
{
if (audio_capture == null || !audio_capture.IsRunning)
{
button_Start.Text = "Stop Recording";
groupBox_RecorderParameters.Enabled = false;
this.StartRecording();
}
else
{
button_Start.Text = "Start Recording";
groupBox_RecorderParameters.Enabled = true;
this.StopRecording();
}
}
private void timer_UpdateSamples_Tick(object sender, EventArgs e)
{
this.UpdateSamples();
}
private void Parrot_FormClosing(object sender, FormClosingEventArgs e)
{
this.StopRecording();
}
#endregion
#region Private Members
void StartRecording()
{
try
{
audio_context = new AudioContext();
}
catch (AudioException ae)
{
MessageBox.Show("Fatal: Cannot continue without a playback device.\nException caught when opening playback device.\n" + ae.Message);
Application.Exit();
}
AL.Listener(ALListenerf.Gain, (float)numericUpDown_PlaybackGain.Value);
src = AL.GenSource();
int sampling_rate = (int)numericUpDown_Frequency.Value;
double buffer_length_ms = (double)numericUpDown_BufferLength.Value;
int buffer_length_samples = (int)((double)numericUpDown_BufferLength.Value * sampling_rate * 0.001 / BlittableValueType.StrideOf(buffer));
try
{
audio_capture = new AudioCapture((string)comboBox_RecorderSelection.SelectedItem,
sampling_rate, ALFormat.Mono16, buffer_length_samples);
}
catch (AudioDeviceException ade)
{
MessageBox.Show("Exception caught when opening recording device.\n" + ade.Message);
audio_capture = null;
}
if (audio_capture == null)
return;
audio_capture.Start();
timer_GetSamples.Start();
timer_GetSamples.Interval = (int)(buffer_length_ms / 2 + 0.5); // Tick when half the buffer is full.
}
void StopRecording()
{
timer_GetSamples.Stop();
if (audio_capture != null)
{
audio_capture.Stop();
audio_capture.Dispose();
audio_capture = null;
}
if (audio_context != null)
{
int r;
AL.GetSource(src, ALGetSourcei.BuffersQueued, out r);
ClearBuffers(r);
AL.DeleteSource(src);
audio_context.Dispose();
audio_context = null;
}
}
void UpdateSamples()
{
if (audio_capture == null)
return;
int available_samples = audio_capture.AvailableSamples;
if (available_samples * SampleToByte > buffer.Length * BlittableValueType.StrideOf(buffer))
{
buffer = new short[OpenTK.Functions.NextPowerOfTwo(
(int)(available_samples * SampleToByte / (double)BlittableValueType.StrideOf(buffer) + 0.5))];
}
if (available_samples > 0)
{
audio_capture.ReadSamples(buffer, available_samples);
int buf = AL.GenBuffer();
AL.BufferData(buf, ALFormat.Mono16, buffer, (int)(available_samples * BlittableValueType.StrideOf(buffer)), audio_capture.SampleFrequency);
AL.SourceQueueBuffer(src, buf);
label_SamplesConsumed.Text = "Samples consumed: " + available_samples;
if (AL.GetSourceState(src) != ALSourceState.Playing)
AL.SourcePlay(src);
}
ClearBuffers(0);
}
void ClearBuffers(int input)
{
if (audio_context == null || audio_context == null)
return;
int[] freedbuffers;
if (input == 0)
{
int BuffersProcessed;
AL.GetSource(src, ALGetSourcei.BuffersProcessed, out BuffersProcessed);
if (BuffersProcessed == 0)
return;
freedbuffers = AL.SourceUnqueueBuffers(src, BuffersProcessed);
}
else
{
freedbuffers = AL.SourceUnqueueBuffers(src, input);
}
AL.DeleteBuffers(freedbuffers);
}
#endregion
#region Main
[STAThread]
static void Main()
{
using (Parrot parrot = new Parrot())
{
parrot.ShowDialog();
}
}
#endregion
}
}

View file

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="label_RINGBUFFER.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label_SamplesConsumed.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label_SamplesConsumed.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="timer_GetSamples.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>