我需要帮助..我有分裂左和右的问题来自麦克风(或声卡)的捕获流的右声道 下面的代码核心记录来自麦克风的声音并保存到wav文件中 对左通道,右通道,左... 如何识别(拆分)CapturedData左右声道? [方法CreateCaptureBuffer()]
对于InPos = 1到24000 - 1步骤2 buffLeft(OutPos)= CaptureData(InPos) OutPos + = 1 下一个InPos
我厌倦了不成功的尝试......
此致 Schift
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
答案 0 :(得分:0)
编写一个directshow过滤器,将其分成两个音频输出?