تشغيل الصوت في .NET باستخدام بيانات الموجية التي تم إنشاؤها
سؤال
كيف يمكنني تشغيل صوتا يعتمد على بيانات الموجي التي يقوم بها برنامج .NET الخاص بي من إدخال المستخدم والوظائف الرياضية؟
عن طريق "بيانات الموجية" أقصد القيم SPL (مستوى ضغط الصوت) في سلسلة زمنية ثابتة ثابتة (ربما 44.1 كيلو هرتز). أفترض أن هذا يتطلب نوعا من الترتيب المخزن المؤقت البث.
ملاحظة، أن هذا يجب أن يكون العيش / في الوقت الحقيقي، لذلك فقط إنشاء ملف .wav ثم اللعب الذي لن يكون كافيا. vb.net المفضل، ولكن C # مقبول أيضا.
فقط لتوضيح: ما أبحث عنه هو مثال رمز العمل بسيط.
المحلول
يمكنك القيام بذلك باستخدام نوديو. وبعد يمكنك إنشاء دفق يستمد من Wavestream وطريقة قراءة التغذية الخاصة به، فأنت بإرجاع العينات التي يمكنك توليدها أثناء الطيران. لديك التحكم في حجم المخازن المؤقتة المستخدمة من قبل بطاقة الصوت التي تمنحك السيطرة على الكمون.
نصائح أخرى
كيفية اللعب من مجموعة من الزوجي
PlayerEx pl = new PlayerEx();
private static void PlayArray(PlayerEx pl)
{
double fs = 8000; // sample freq
double freq = 1000; // desired tone
short[] mySound = new short[4000];
for (int i = 0; i < 4000; i++)
{
double t = (double)i / fs; // current time
mySound[i] = (short)(Math.Cos(t * freq) * (short.MaxValue));
}
IntPtr format = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs);
pl.OpenPlayer(format);
byte[] mySoundByte = new byte[mySound.Length * 2];
Buffer.BlockCopy(mySound, 0, mySoundByte, 0, mySoundByte.Length);
pl.AddData(mySoundByte);
pl.StartPlay();
}
الدفع هذا الموضوع على تحميل ما يصل صوت مباشر مخزن مؤقت مع بيانات تعسفية ولعبها.
لكل تعليق: نعم، أعرف. ستحتاج إلى ترجمة C ++ إلى C # أو vb.net. ولكن، فإن المفهوم هو ما هو مهم. يمكنك إنشاء مخزن مؤقت DirectSound ثانوي ثم استخدمه للدفق إلى المخزن المؤقت الأساسي واللعب.
لدي هذا الرمز ولكن يجب أن يكون لديك رمز لإنشاء ملف WAV الخاص بك في الذاكرة.
Option Strict Off
Option Explicit On
Imports Microsoft.DirectX.DirectSound
Imports Microsoft.DirectX
Imports System.Threading
Public Class Form1
Const SRATE As Integer = 44100
Const FREQ As Integer = 440
Const DUR As Integer = 1
Private dsDesc As BufferDescription
Private wvFormat As WaveFormat
Private DS As Device
Dim SecondaryBuffer As Microsoft.DirectX.DirectSound.SecondaryBuffer
Dim BufferDescription As Microsoft.DirectX.DirectSound.BufferDescription
Dim DXFormat As Microsoft.DirectX.DirectSound.WaveFormat
Dim sbuf(DUR * SRATE) As Short
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Show()
DS = New Microsoft.DirectX.DirectSound.Device
DS.SetCooperativeLevel(Me, CooperativeLevel.Normal)
wvFormat.FormatTag = WaveFormatTag.Pcm
wvFormat.Channels = 1
wvFormat.SamplesPerSecond = SRATE
wvFormat.BitsPerSample = 16
wvFormat.AverageBytesPerSecond = 2 * SRATE
wvFormat.BlockAlign = 2
dsDesc = New BufferDescription(wvFormat)
dsDesc.BufferBytes = 2 * DUR * SRATE
dsDesc.Flags = 0
Dim buff1 = PlayWave(400)
Dim buff2 = PlayWave(600)
buff1 = PlayWave(400)
buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default)
Thread.Sleep(1000)
buff1 = PlayWave(600)
buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default)
' End
End Sub
Function PlayWave(FREQ As Integer) As SecondaryBuffer
' create a buffer
Dim dsBuffer As SecondaryBuffer
dsBuffer = New SecondaryBuffer(dsDesc, DS)
Dim sbuf(DUR * SRATE) As Short
' create tone
For i As Integer = 0 To DUR * SRATE
sbuf(i) = CShort(10000 * Math.Sin(2 * Math.PI * FREQ * i / SRATE))
Next
' copy to buffer
dsBuffer.Write(0, sbuf, LockFlag.EntireBuffer)
Return dsBuffer
End Function