Last active
January 5, 2024 17:54
-
-
Save fukuroder/af06033821c034b3daa2ddc39e5c6906 to your computer and use it in GitHub Desktop.
WASAPI capture in F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System.Runtime.InteropServices | |
open NAudio.CoreAudioApi | |
module NativeMethods = | |
[<DllImport("api-ms-win-core-synch-l1-2-0.dll")>] | |
extern System.IntPtr CreateEvent(System.IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, System.IntPtr lpName) | |
[<DllImport("api-ms-win-core-handle-l1-1-0.dll")>] | |
extern bool CloseHandle(System.IntPtr hObject) | |
[<DllImport("api-ms-win-core-synch-l1-2-0.dll")>] | |
extern int WaitForSingleObject(System.IntPtr hEvent, int milliseconds) | |
[<EntryPoint>] | |
let main args = | |
// デフォルトのキャプチャデバイス取得 | |
let deviceEnumerator = new MMDeviceEnumerator() | |
let device = (DataFlow.Capture, Role.Console) |> deviceEnumerator.GetDefaultAudioEndpoint | |
printfn "Default Capture Device: %s" device.FriendlyName | |
// AudioClient取得 | |
let client = device.AudioClient | |
// 初期化 | |
( | |
AudioClientShareMode.Shared, | |
AudioClientStreamFlags.EventCallback, | |
client.DefaultDevicePeriod, | |
client.DefaultDevicePeriod, | |
(48000, 16, 2) |> NAudio.Wave.WaveFormat, | |
System.Guid.Empty | |
) |> client.Initialize | |
// バッファイベントを登録する | |
let frameEventWaitHandle = (System.IntPtr.Zero, false, false, System.IntPtr.Zero) |> NativeMethods.CreateEvent | |
frameEventWaitHandle |> client.SetEventHandle | |
// バッファサイズを取得する | |
let bufsize = client.BufferSize | |
// AudioCaptureClient取得 | |
let captureClient = client.AudioCaptureClient | |
// キャプチャ開始 | |
() |> client.Start | |
let mutable stop = false | |
async{ | |
// Enterキーが押されたら終了 | |
() |> stdin.ReadLine |> ignore | |
printfn "enter key pressed" | |
stop <- true | |
} |> Async.StartAsTask |> ignore | |
while not stop do | |
// バッファがいっぱいになるまで待つ | |
(frameEventWaitHandle, -1) |> NativeMethods.WaitForSingleObject |> ignore | |
// バッファ取得 | |
let mutable numFrameToRead = 0 | |
let mutable bufferFlags = AudioClientBufferFlags.None | |
let p = captureClient.GetBuffer(&numFrameToRead, &bufferFlags) | |
match bufferFlags with | |
| AudioClientBufferFlags.None -> | |
printfn "numFrameToRead: %d" numFrameToRead | |
////////////// | |
// 何かする // | |
////////////// | |
| _ -> () | |
// バッファ解放 | |
numFrameToRead |> captureClient.ReleaseBuffer | |
done | |
// キャプチャ停止 | |
() |> client.Stop | |
// 後始末 | |
frameEventWaitHandle |> NativeMethods.CloseHandle |> ignore | |
() |> client.Dispose | |
() |> device.Dispose | |
() |> deviceEnumerator.Dispose | |
0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment