0

助けが必要.. マイク (またはサウンド カード) からキャプチャされたストリームから左右のチャネルを分割する際に問題があります。以下のコードは、マイクからサウンドを正確に録音し、左チャネル、右チャネル、左のペアの wav ファイルに保存します。 (分割) CapturedData の左チャネルと右チャネル ?? [メソッド CreateCaptureBuffer()]

For InPos = 1 ~ 24000 - 1 ステップ 2 buffLeft(OutPos) = CaptureData(InPos) OutPos += 1 次の InPos


私は失敗した試みにうんざりしています...

よろしく、 シフト

Imports Microsoft.DirectX
Imports Microsoft.DirectX.DirectSound
Imports System.Threading
Imports System.IO


Public Class Form1
Public PositionNotify As BufferPositionNotify() = New Microsoft.DirectX.DirectSound.BufferPositionNotify(NumberRecordNotifications) {}
Public Const NumberRecordNotifications As Integer = 16
Public NotificationEvent As AutoResetEvent = Nothing
Public applicationBuffer As CaptureBuffer = Nothing
Public CaptureDeviceGuid As Guid = Guid.Empty
Public applicationDevice As Capture = Nothing

Private FileName As String = String.Empty
Private FileName2 As String = String.Empty

Public applicationNotify As Notify = Nothing
Private NotifyThread As Thread = Nothing

Private Wave As FileStream = Nothing

Private Writer As BinaryWriter = Nothing

Private Path As String = String.Empty
Public CaptureBufferSize As Integer = 0
Public NextCaptureOffset As Integer = 0
Private Recording As Boolean = False
Public InputFormat As WaveFormat
Private SampleCount As Integer = 0
Public NotifySize As Integer = 0
Private counter As Integer = 0
Private Capturing As Boolean = False

Private strx As New MemoryStream


Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim captureDevicesCollection As New CaptureDevicesCollection
Console.WriteLine(captureDevicesCollection(2).Description)
CaptureDeviceGuid = captureDevicesCollection(2).DriverGuid
With InputFormat
.AverageBytesPerSecond = 192000
.BitsPerSample = 16
.BlockAlign = 4
.Channels = 2
.FormatTag = WaveFormatTag.Pcm
.SamplesPerSecond = 48000
End With
FileName = "C:\test.wav"
' FileName2 = "C:\testLeft.wav"
Try
applicationDevice = New Capture(CaptureDeviceGuid)
CreateCaptureBuffer()
OnCreateSoundFile()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub

Private Sub CreateCaptureBuffer()
'-----------------------------------------------------------------------------
' Name: CreateCaptureBuffer()
' Desc: Creates a capture buffer and sets the format 
'-----------------------------------------------------------------------------
Dim dscheckboxd As New CaptureBufferDescription()

If applicationNotify IsNot Nothing Then
applicationNotify.Dispose()
applicationNotify = Nothing
End If
If applicationBuffer IsNot Nothing Then
applicationBuffer.Dispose()
applicationBuffer = Nothing
End If

If 0 = InputFormat.Channels Then
Return
End If

' Set the notification size
NotifySize = IIf((1024 > InputFormat.AverageBytesPerSecond / 8), 1024, (InputFormat.AverageBytesPerSecond / 8))
NotifySize -= NotifySize Mod InputFormat.BlockAlign

' Set the buffer sizes
CaptureBufferSize = NotifySize * NumberRecordNotifications

' Create the capture buffer
dscheckboxd.BufferBytes = CaptureBufferSize
InputFormat.FormatTag = WaveFormatTag.Pcm
dscheckboxd.Format = InputFormat
' Set the format during creatation
applicationBuffer = New CaptureBuffer(dscheckboxd, applicationDevice)
NextCaptureOffset = 0

InitNotifications()
End Sub

Private Sub InitNotifications()
'-----------------------------------------------------------------------------
' Name: InitNotifications()
' Desc: Inits the notifications on the capture buffer which are handled
' in the notify thread.
'-----------------------------------------------------------------------------

If applicationBuffer Is Nothing Then
Throw New NullReferenceException()
End If

' Create a thread to monitor the notify events
If NotifyThread Is Nothing Then
NotifyThread = New Thread(New ThreadStart(AddressOf WaitThread))
Capturing = True
NotifyThread.Start()

' Create a notification event, for when the sound stops playing
NotificationEvent = New AutoResetEvent(False)
End If


' Setup the notification positions
For i As Integer = 0 To NumberRecordNotifications - 1
PositionNotify(i).Offset = (NotifySize * i) + NotifySize - 1
PositionNotify(i).EventNotifyHandle = NotificationEvent.Handle
Next

applicationNotify = New Notify(applicationBuffer)

' Tell DirectSound when to notify the app. The notification will come in the from 
' of signaled events that are handled in the notify thread.
applicationNotify.SetNotificationPositions(PositionNotify, NumberRecordNotifications)
End Sub

Private Sub WaitThread()
While Capturing
'Sit here and wait for a message to arrive
NotificationEvent.WaitOne(Timeout.Infinite, True)
RecordCapturedData()
End While
End Sub

Private Sub RecordCapturedData()
'-----------------------------------------------------------------------------
' Name: RecordCapturedData()
' Desc: Copies data from the capture buffer to the output buffer 
'-----------------------------------------------------------------------------
Dim CaptureData As Byte() = Nothing
Dim buffLeft As Byte() = Nothing
Dim buffRight As Byte() = Nothing
Dim ReadPos As Integer
Dim CapturePos As Integer
Dim LockSize As Integer

applicationBuffer.GetCurrentPosition(CapturePos, ReadPos)
LockSize = ReadPos - NextCaptureOffset
If LockSize < 0 Then
LockSize += CaptureBufferSize
End If

' Block align lock size so that we are always write on a boundary
LockSize -= (LockSize Mod NotifySize)

If 0 = LockSize Then
Return
End If

' Read the capture buffer.
CaptureData = DirectCast(applicationBuffer.Read(NextCaptureOffset, GetType(Byte), LockFlag.None, LockSize), Byte())

ReDim buffLeft(24000)
' ReDim buffLeft(UBound(CaptureData))
''ReDim buffRight(UBound(buffLeft))
Dim InPos As Long = 0
Dim OutPos As Long = 0
Dim counter As Long = 0

For InPos = 1 To 24000 - 1 Step 2
buffLeft(OutPos) = CaptureData(InPos)
OutPos += 1
Next InPos

SampleCount += buffLeft.Length - 1
Writer.Write(buffLeft, 0, buffLeft.Length - 1)

' Move the capture offset along
NextCaptureOffset += CaptureData.Length
NextCaptureOffset = NextCaptureOffset Mod CaptureBufferSize
' Circular buffer
End Sub

Private Sub checkboxRecord_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles checkboxRecord.CheckedChanged
Recording = Not Recording
StartOrStopRecord(Recording)

If Not Recording Then
checkboxRecord.Enabled = False
End If
End Sub

Private Sub StartOrStopRecord(ByVal StartRecording As Boolean)
'-----------------------------------------------------------------------------
' Name: StartOrStopRecord()
' Desc: Starts or stops the capture buffer from recording
'-----------------------------------------------------------------------------

If StartRecording Then
' Create a capture buffer, and tell the capture 
' buffer to start recording 
CreateCaptureBuffer()
applicationBuffer.Start(True)
Else
' Stop the buffer, and read any data that was not 
' caught by a notification
applicationBuffer.[Stop]()

RecordCapturedData()

Writer.Seek(4, SeekOrigin.Begin)
' Seek to the length descriptor of the RIFF file.
Writer.Write(CInt(SampleCount + 36))
' Write the file length, minus first 8 bytes of RIFF description.
Writer.Seek(40, SeekOrigin.Begin)
' Seek to the data length descriptor of the RIFF file.
Writer.Write(SampleCount)
' Write the length of the sample data in bytes.
Writer.Close()
' Close the file now.
Writer = Nothing
'<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>
'-------------------------------------
' Set the writer to null.
' Set the FileStream to null.
Wave = Nothing
End If
End Sub


Private Sub CreateRIFF()
'*************************************************************************
' 
' Here is where the file will be created. A
' wave file is a RIFF file, which has chunks
' of data that describe what the file contains.
' A wave RIFF file is put together like this:
' 
' The 12 byte RIFF chunk is constructed like this:
' Bytes 0 - 3 : 'R' 'I' 'F' 'F'
' Bytes 4 - 7 : Length of file, minus the first 8 bytes of the RIFF description.
' (4 bytes for "WAVE" + 24 bytes for format chunk length +
' 8 bytes for data chunk description + actual sample data size.)
' Bytes 8 - 11: 'W' 'A' 'V' 'E'
' 
' The 24 byte FORMAT chunk is constructed like this:
' Bytes 0 - 3 : 'f' 'm' 't' ' '
' Bytes 4 - 7 : The format chunk length. This is always 16.
' Bytes 8 - 9 : File padding. Always 1.
' Bytes 10- 11: Number of channels. Either 1 for mono, or 2 for stereo.
' Bytes 12- 15: Sample rate.
' Bytes 16- 19: Number of bytes per second.
' Bytes 20- 21: Bytes per sample. 1 for 8 bit mono, 2 for 8 bit stereo or
' 16 bit mono, 4 for 16 bit stereo.
' Bytes 22- 23: Number of bits per sample.
' 
' The DATA chunk is constructed like this:
' Bytes 0 - 3 : 'd' 'a' 't' 'a'
' Bytes 4 - 7 : Length of data, in bytes.
' Bytes 8 -...: Actual sample data.
' 
' **************************************************************************


' Open up the wave file for writing.
Wave = New FileStream(FileName, FileMode.Create)
' WaveFileLeft = New FileStream(FileName2, FileMode.Create)
Writer = New BinaryWriter(Wave)

' Set up file with RIFF chunk info.
Dim ChunkRiff As Char() = {"R"c, "I"c, "F"c, "F"c}
Dim ChunkType As Char() = {"W"c, "A"c, "V"c, "E"c}
Dim ChunkFmt As Char() = {"f"c, "m"c, "t"c, " "c}
Dim ChunkData As Char() = {"d"c, "a"c, "t"c, "a"c}

Dim shPad As Short = 1
' File padding
Dim nFormatChunkLength As Integer = &H10
' Format chunk length.
Dim nLength As Integer = 0
' File length, minus first 8 bytes of RIFF description. This will be filled in later.
Dim shBytesPerSample As Short = 0
' Bytes per sample.
' Figure out how many bytes there will be per sample.
If 8 = InputFormat.BitsPerSample AndAlso 1 = InputFormat.Channels Then
shBytesPerSample = 1
ElseIf (8 = InputFormat.BitsPerSample AndAlso 2 = InputFormat.Channels) OrElse (16 = InputFormat.BitsPerSample AndAlso 1 = InputFormat.Channels) Then
shBytesPerSample = 2
ElseIf 16 = InputFormat.BitsPerSample AndAlso 2 = InputFormat.Channels Then
shBytesPerSample = 4
End If

' Fill in the riff info for the wave file.
Writer.Write(ChunkRiff)
Writer.Write(nLength)
Writer.Write(ChunkType)

'.AverageBytesPerSecond = 192000
'.BitsPerSample = 16
'.BlockAlign = 4
'.Channels = 2
'.FormatTag = WaveFormatTag.Pcm
'.SamplesPerSecond = 48000

' Fill in the format info for the wave file.
Writer.Write(ChunkFmt)
Writer.Write(nFormatChunkLength)
Writer.Write(shPad)
Writer.Write(InputFormat.Channels) 'channels
Writer.Write(InputFormat.SamplesPerSecond) 'samplepersecond
Writer.Write(InputFormat.AverageBytesPerSecond) 'averagebytespersecond
Writer.Write(shBytesPerSample) 'bytespersample
Writer.Write(InputFormat.BitsPerSample) 'bitspersample

' Now fill in the data chunk.
Writer.Write(ChunkData)
Writer.Write(CInt(0))
' The sample length will be written in later.
'<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>

End Sub

Private Sub OnCreateSoundFile()
'-----------------------------------------------------------------------------
' Name: OnCreateSoundFile()
' Desc: Called when the user requests to save to a sound file
'-----------------------------------------------------------------------------

If Recording Then
' Stop the capture and read any data that 
' was not caught by a notification
StartOrStopRecord(False)
Recording = False
End If

' Update the UI controls to show the sound as loading a file
checkboxRecord.Enabled = False
Try
CreateRIFF()
Catch

End Try

' Update the UI controls to show the sound as the file is loaded
labelFilename.Text = FileName
checkboxRecord.Enabled = True

' Remember the path for next time
Path = FileName.Substring(0, FileName.LastIndexOf("\"))
End Sub

End Class
4

1 に答える 1

0

2 つのオーディオ出力に分割する directshow フィルターを作成しますか?

于 2010-08-01T05:09:58.220 に答える