На момент написания статьи никто не обращался к 32-битным или 64-битным кодированным WAV.
Следующий код обрабатывает 16/32/64 бит и моно / стерео:
static bool readWav( string filename, out float[] L, out float[] R )
{
L = R = null;
//float [] left = new float[1];
//float [] right;
try {
using (FileStream fs = File.Open(filename,FileMode.Open))
{
BinaryReader reader = new BinaryReader(fs);
// chunk 0
int chunkID = reader.ReadInt32();
int fileSize = reader.ReadInt32();
int riffType = reader.ReadInt32();
// chunk 1
int fmtID = reader.ReadInt32();
int fmtSize = reader.ReadInt32(); // bytes for this chunk
int fmtCode = reader.ReadInt16();
int channels = reader.ReadInt16();
int sampleRate = reader.ReadInt32();
int byteRate = reader.ReadInt32();
int fmtBlockAlign = reader.ReadInt16();
int bitDepth = reader.ReadInt16();
if (fmtSize == 18)
{
// Read any extra values
int fmtExtraSize = reader.ReadInt16();
reader.ReadBytes(fmtExtraSize);
}
// chunk 2
int dataID = reader.ReadInt32();
int bytes = reader.ReadInt32();
// DATA!
byte[] byteArray = reader.ReadBytes(bytes);
int bytesForSamp = bitDepth/8;
int samps = bytes / bytesForSamp;
float[] asFloat = null;
switch( bitDepth ) {
case 64:
double[]
asDouble = new double[samps];
Buffer.BlockCopy(byteArray, 0, asDouble, 0, bytes);
asFloat = Array.ConvertAll( asDouble, e => (float)e );
break;
case 32:
asFloat = new float[samps];
Buffer.BlockCopy(byteArray, 0, asFloat, 0, bytes);
break;
case 16:
Int16 []
asInt16 = new Int16[samps];
Buffer.BlockCopy(byteArray, 0, asInt16, 0, bytes);
asFloat = Array.ConvertAll( asInt16, e => e / (float)Int16.MaxValue );
break;
default:
return false;
}
switch( channels ) {
case 1:
L = asFloat;
R = null;
return true;
case 2:
L = new float[samps];
R = new float[samps];
for( int i=0, s=0; i<samps; i++ ) {
L[i] = asFloat[s++];
R[i] = asFloat[s++];
}
return true;
default:
return false;
}
}
}
catch {
Debug.Log( "...Failed to load note: " + filename );
return false;
//left = new float[ 1 ]{ 0f };
}
return false;
}
Вот пример одного из способов сделать то, что вы хотите:
Во-первых, код - UserControl1.xaml.cs
public partial class UserControl1 : UserControl
{
public static readonly DependencyProperty MyContentProperty =
DependencyProperty.Register("MyContent", typeof(object), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
public object MyContent
{
get { return GetValue(MyContentProperty); }
set { SetValue(MyContentProperty, value); }
}
}
И XAML пользовательского элемента управления - UserControl1.xaml
<UserControl x:Class="InCtrl.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300" Name="MyCtrl">
<StackPanel>
<Button Content="Up"/>
<ContentPresenter Content="{Binding ElementName=MyCtrl, Path=MyContent}"/>
<Button Content="Down"/>
</StackPanel>
</UserControl>
И, наконец, xaml для использования нашего замечательного нового элемента управления:
<Window x:Class="InCtrl.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:InCtrl"
Title="Window1" Height="300" Width="300">
<Grid>
<me:UserControl1>
<me:UserControl1.MyContent>
<Button Content="Middle"/>
</me:UserControl1.MyContent>
</me:UserControl1>
</Grid>
</Window>
Мне сложно понять ваш вопрос, но я думаю, что вы описываете ItemsControl
, использующий DataTemplates
для отображения содержимого (предположительно) ObservableCollection (T) .
UserControl может быть не лучшим способом сделать это. Вы хотите добавить украшения вокруг содержимого, что в основном и делает Border: у него есть дочерний элемент и он добавляет свой собственный материал по краям.
Посмотрите на класс Decorator, от которого происходит Border. Если вы создадите своего собственного потомка Border, вы легко сможете делать то, что хотите. Однако я считаю, что это потребует написания кода, а не XAML.
Вы все равно можете захотеть сделать UserControl для обертывания кнопок внизу, чтобы вы могли использовать визуальный конструктор для части процесса. Но Decorator был бы хорошим способом склеить части вместе и позволить пользовательский контент.