#vb.net
Вопрос:
Я играю синусоидальную волну на частоте 1 кГц, созданную классом, который реализует NAudio IWaveProvider. Хотя я изменяю амплитуду синусоидальной волны на разных уровнях, WaveOut всегда воспроизводится на максимальной громкости. Вот это vb.net код:
Public Class Audio
Public MustInherit Class WaveProvider32
Implements Wave.IWaveProvider
Private _waveFormat As NAudio.Wave.WaveFormat
Public Sub New()
Me.New(44100, 1)
End Sub
Public Sub New(ByVal sampleRate As Integer, ByVal channels As Integer)
MyBase.New
Me.SetWaveFormat(sampleRate, channels)
End Sub
Public Sub SetWaveFormat(ByVal sampleRate As Integer, ByVal channels As Integer)
_waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels)
End Sub
Public Overloads Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer
Dim waveBuffer As WaveBuffer = New WaveBuffer(buffer)
Dim samplesRequired As Integer = count / 4
Dim samplesRead As Integer = Me.Read(waveBuffer.FloatBuffer, offset / 4, samplesRequired)
Return samplesRead * 4
End Function
Public MustOverride Overloads Function Read(ByVal buffer() As Single, ByVal offset As Integer, ByVal sampleCount As Integer) As Integer
Public MustOverride Function IWaveProvider_Read(buffer() As Byte, offset As Integer, count As Integer) As Integer Implements Wave.IWaveProvider.Read
Public ReadOnly Property WaveFormat As WaveFormat
Get
Return _waveFormat
End Get
End Property
Public MustOverride ReadOnly Property IWaveProvider_WaveFormat As Wave.WaveFormat Implements Wave.IWaveProvider.WaveFormat
End Class
Public Class SineWaveProvider32Ex
Inherits WaveProvider32
Shadows waveFormat As WaveFormat
Private m_fAmplitude As Single
Private m_fFrequency As Single
Private m_nSample As Integer
Private m_bitPerSample As Integer
Private m_waveFileWriter As WaveFileWriter
Public Sub New(ByVal waveFileWriter As WaveFileWriter, ByVal sampleRate As Integer, ByVal channels As Integer, ByVal Amplitude As Single, ByVal Frequency As Single, ByVal BitPerSample As Integer)
MyBase.New
Me.m_waveFileWriter = waveFileWriter
Me.m_fAmplitude = Amplitude
Me.m_fFrequency = Frequency
Me.m_bitPerSample = BitPerSample
SetWaveFormat(sampleRate, channels, BitPerSample)
End Sub
Public Property Frequency As Single
Get
Return Frequency
End Get
Set
m_fFrequency = Value
End Set
End Property
Public Property Amplitude As Single
Get
Return Amplitude
End Get
Set
m_fAmplitude = Value
End Set
End Property
Public Overrides ReadOnly Property IWaveProvider_WaveFormat As WaveFormat
Get
Return waveFormat
End Get
End Property
Public Overrides Function Read(buffer() As Single, offset As Integer, sampleCount As Integer) As Integer
Dim sampleRate As Integer = waveFormat.SampleRate
Dim n As Integer = 0
Do While (n < sampleCount)
buffer(n offset) = CType(m_fAmplitude * Math.Sin(2 _
* (Math.PI _
* (m_nSample * m_fFrequency)) _
/ sampleRate), Single)
If m_fFrequency = 0 Then
If m_fAmplitude = 1.0! Then
m_fAmplitude = 0.9999999!
ElseIf m_fAmplitude = -1.0! Then
m_fAmplitude = -0.9999999!
End If
buffer(n offset) = CType(m_fAmplitude, Single)
End If
m_nSample = (m_nSample 1)
If (m_nSample >= sampleRate) Then
m_nSample = 0
End If
If m_waveFileWriter IsNot Nothing Then
m_waveFileWriter.WriteSample(buffer((n offset)))
End If
n = (n 1)
Loop
Return sampleCount
End Function
Public Overrides Function IWaveProvider_Read(buffer() As Byte, offset As Integer, count As Integer) As Integer
Dim waveBuffer As WaveBuffer = New WaveBuffer(buffer)
Dim samplesRequired As Integer = (count / 4)
Dim samplesRead As Integer = Read(waveBuffer.FloatBuffer, (offset / 4), samplesRequired)
Return (samplesRead * 4)
End Function
Public Overloads Sub SetWaveFormat(ByVal sampleRate As Integer, ByVal channels As Integer, BitPerSample As Integer)
Me.waveFormat = New WaveFormat(sampleRate, BitPerSample, channels)
End Sub
End Class
End Class
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim tempFile As String = "C:TempTest.wav"
Dim input As Audio.SineWaveProvider32Ex
If (waveOut Is Nothing) Then
MyWaveFileWriter = New WaveFileWriter(tempFile, New WaveFormat(192000, 24, 2))
input = New Audio.SineWaveProvider32Ex(MyWaveFileWriter, 192000, 2, 1.0! / (Math.Pow(2, 2)), 1000.0!, 24)
waveOut = New WaveOut
waveOut.Init(input)
waveOut.Play()
Else
waveOut.Stop()
waveOut.Dispose()
waveOut = Nothing
MyWaveFileWriter.Close()
End If
End Sub
Я изменяю свойство амплитуды с 1.0! / (Математическое значение(2, 0)) на 1.0! / (Математическое значение(2, 23)), но ничего не меняется, всегда максимальная громкость.
Любопытно, что если я воспроизведу сохраненный wav-файл (который был записан с правильной амплитудой) с помощью WaveFileReader, выходной звук будет отображаться с правильной амплитудой.
Кто-нибудь может помочь?
Спасибо