marabunta
Goto Top

PowerShell Mikrofonpegel erfassen

Hallo,

ich hatte eine Idee, eine Art Aktivität des Sprechens zu messen.
Dafür will ich nicht das Mikrofon mitschneiden, nicht den Pegel ändern, sondern rein den Wert abfragen, ob >=50% Ausschlag vorhanden sind.
Nach ca. 1 Minute stille, etwas ausführen.

Dazu habe ich mit den verwendeten Suchbegriffen noch nichts finden können, weiß jemand mehr?
Danke.

Content-ID: 894084828

Url: https://administrator.de/contentid/894084828

Printed on: December 2, 2024 at 17:12 o'clock

148656
148656 Jul 03, 2021 updated at 17:04:11 (UTC)
Goto Top
Moin,

diese Idee ist nicht neu hier im Forum.
PowerShell Audio Erkennung auf Line
Leider hat der User seine Fortschritte nicht mit der Community geteilt.

Gruß
C.C.
Marabunta
Marabunta Jul 03, 2021 at 18:07:05 (UTC)
Goto Top
In Visual Studio bekomme ich da nur Fehler beim bauen, bin nicht tief genug drin um die zu beheben.
143611
143611 Jul 04, 2021 updated at 08:29:38 (UTC)
Goto Top
Moin,

Du könntest Die NAudio-Bibliothek verwenden und dann folgender Anleitung folgen.

Viel Erfolg!

P.S. Event handler in der posh sind ein bisschen tricky. Eine gute Übersicht über das generelle Vorgehen gibt's hier
colinardo
Solution colinardo Jul 04, 2021, updated at May 11, 2022 at 13:55:51 (UTC)
Goto Top
Servus,
hier mal ein einfaches Beispiel mit der von @143611 genannten naudio Bibliothek, welches den Input-Level auf der Konsole kontinuierlich ausgibt.
Das Input-Device wird im Skript zu Beginn abgefragt. (Hinweis: Bitte nicht in der Powershell ISE laufen lassen sondern in einer normalen Konsole).
Das mit dem "nach 1 Minute Stille" bekommst du sicher auch selbst hin, da reicht ja eine Variable mit get-time auszustatten und diese dann regelmäßig zu aktualisieren falls sich der Pegel über ein bestimmtes Level bewegt, die Abfrage der Variablen mit dem Vergleich der aktuellen Zeit mittels IF Abfrage liefert dir dann den Zeitraum wie lange es still war und startet dann deine Aktion. Du musst ja auch noch was zum Scripten haben, den Spaß will ich dir nicht nehmen face-wink

# Auszug ...

# choose input device
write-host "Select your input device:`n" -F Green  
$dcount = [NAudio.Wave.WaveIn]::DeviceCount
$device = 0
do{
    1..$dcount | %{
        write-host "`t[$($_)]`t$([naudio.wave.wavein]::GetCapabilities(($_-1)).ProductName)"  
    }
    try{
        [int]$device = read-host "`nEnter number"  
    }catch{}
    if ($device -notin 1..$dcount){
        Write-Warning "No valid input, please repeat.`n`n"  
    }
}until($device -in 1..$dcount)
$device--
# Create Recording-Device
$global:wave = New-Object NAudio.Wave.WaveInEvent -Property @{
    # define recording device index
    DeviceNumber = $device
    # set recording format (32khz, 16Bits, mono)
    WaveFormat = New-Object NAudio.Wave.WaveFormat 32000,16,1
    BufferMilliseconds = 100
}
# register DataAvailable event handler
Register-ObjectEvent $global:wave DataAvailable -SourceIdentifier SoundRecording -Action {
        $max = 0
        $bps = $global:wave.WaveFormat.BitsPerSample / 8
        # calculate peak
        for ($i = 0; $i -lt ([int]$event.SourceEventArgs.BytesRecorded / $bps) ; $i++){
            $max = [Math]::Max($max, [System.BitConverter]::ToInt16($event.SourceEventArgs.Buffer,$i * 2))
        }
        # calculate percentage
        [int]$percent = ($max / [int16]::MaxValue) * 100
        cls
        write-host "Level: $percent %" -F Green  
} | out-null
# Start recording input
$global:wave.StartRecording()
# stop recording after pressing escape
read-host "`nAfter pressing Enter recording will start (press ESC to stop) ..."  
while ($true){
    if ($host.name -eq 'consolehost'){  
        if([Console]::KeyAvailable -and [Console]::ReadKey().Key -eq [ConsoleKey]::Escape){
            $global:wave.StopRecording()
            break
        }
    }
    sleep .5
}
back-to-topDas komplette Skript was das Laden der Bibliothek enthält kann hier heruntergeladen werden monitor_input_level_894084828.ps1

Grüße Uwe
--
143611
143611 Jul 04, 2021 at 13:41:25 (UTC)
Goto Top
@colinardo: cool, ich kannte das Register-ObjectEvent CmdLet noch gar nicht - wieder was gelernt 😁