2010-06-21 2 views
0

도움이 필요합니다. 마이크에서 캡처 한 스트림에서 왼쪽 채널을 분할하는 데 문제가 있습니다. 아래의 코드는 마이크에서 코어를 녹음하여 저장합니다. wav 파일 쌍 왼쪽 채널, 오른쪽 채널, 왼쪽 ... CapturedData 왼쪽 및 오른쪽 채널을 인식 (분할)하는 방법 ?? [방법 CreateCaptureBuffer()] INPOS 들어캡처 된 스테레오 사운드를 마이크에서 2 개의 모노 wav로 분할하는 방법

= 1 24000에 1 - 2 단계 buffLeft (OutPos) = CaptureData (INPOS) OutPos는 + = 1 다음 INPOS


I 피곤 실패한 시도 ...

감사합니다, 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

와우, 이것을 읽을 수 있도록 포맷하십시오. :) – InsertNickHere

답변

0

두 개의 오디오 출력으로 나누는 DirectShow 필터를 작성합니까?

관련 문제