2009-07-05 34 views
7

Làm cách nào để phát âm thanh dựa trên dữ liệu dạng sóng mà chương trình .NET của tôi tạo ra từ đầu vào của người dùng và các hàm toán học?Phát âm thanh bằng .NET sử dụng dữ liệu dạng sóng được tạo

Bằng "dữ liệu dạng sóng" tôi ngụ ý các giá trị SPL (mức áp suất âm thanh) trong một chuỗi thời gian cố định khoảng thời gian (có thể là 44,1 kHz). Tôi đoán rằng điều này đòi hỏi một số loại sắp xếp bộ đệm trực tuyến.

Lưu ý rằng điều này phải trực tiếp/thời gian thực, vì vậy chỉ cần tạo tệp .wav và sau đó phát tệp đó sẽ không đủ. VB.NET được ưa thích, nhưng C# cũng được chấp nhận.

Chỉ cần làm rõ: Điều tôi đang tìm kiếm là một ví dụ về mã làm việc đơn giản.

+0

Tôi cuối cùng đã cố gắng để thử giải pháp NAudio, và nó thật tuyệt vời! Vì vậy, tốt hơn nhiều và dễ dàng hơn tôi đã sợ, tôi thực sự nên đã thử nó từ lâu. – RBarryYoung

+1

Câu trả lời hoạt động nhiều hơn cho câu hỏi này là trong câu hỏi Stack Overflow * [NAudio đang chơi sóng sin trong x mili giây bằng C#] (http://stackoverflow.com/questions/5485577) *. –

Trả lời

4

Bạn có thể thực hiện việc này bằng cách sử dụng NAudio. Bạn tạo một luồng có nguồn gốc từ WaveStream và trong phương pháp Read overriden Read của nó, bạn trả về các mẫu mà bạn có thể tạo ra khi đang bay. Bạn có thể kiểm soát kích thước của bộ đệm được sử dụng bởi soundcard cho phép bạn kiểm soát độ trễ.

+0

Cuối cùng tôi đã có cơ hội thử NAudio và nó thật tuyệt vời. Cảm ơn con trỏ. – RBarryYoung

0

Tôi nghĩ bạn cần phải sử dụng DirectSound (DirectX API) cho điều đó. Nó hoạt động ra bộ đệm mà bạn có thể điền vào với dữ liệu được tạo của bạn.

Có lẽ cái gì đó như this (here theo cách trở lại máy) sẽ giúp

1

Check-out this thread trên tải lên một bộ đệm DirectSound với dữ liệu tùy ý và chơi nó.

Mỗi nhận xét: Có, tôi biết. Bạn sẽ cần dịch C++ sang C# hoặc VB.NET. Nhưng, khái niệm là điều quan trọng. Bạn tạo một bộ đệm DirectSound thứ cấp và sau đó sử dụng nó để truyền qua bộ đệm và phát chính của bạn.

+0

Vâng đó là * không * VB.net hoặc C#. Trong thực tế nó không giống như. Net ở tất cả. – RBarryYoung

3

How to play from an array of doubles

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(); 
    } 
0

tôi có mã này nhưng bạn sẽ phải có mã để tạo ra file wav của bạn trong bộ nhớ.

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 
Các vấn đề liên quan