слушатель уровня микрофона

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

слушатель уровня микрофона

Сообщение Invader » 12.05.2014 (Пн) 22:12

искал как можно отследить что в подключенный микрофон говорят, то есть на входе микрофона появляется сигнал отличный от шума. Для автоматизации записи.
Отлично с этим справляется следующий код:
Код: Выделить всё
    Imports System.Runtime.InteropServices
    Public Class Form1
     
        Private Const CALLBACK_FUNCTION = &H30000L
        Private Const MM_WIM_DATA = &H3C0
     
        Private Structure WAVEFORMATEX
            Dim wFormatTag As Int16
            Dim nChannels As Int16
            Dim nSamplesPerSec As Int32
            Dim nAvgBytesPerSec As Int32
            Dim nBlockAlign As Int16
            Dim wBitsPerSample As Int16
            Dim cbSize As Int16
            Sub New(ByVal sample As Int32)
                cbSize = Marshal.SizeOf(Me)
                wFormatTag = 1 : nChannels = 1 : nBlockAlign = 1
                wBitsPerSample = 8 : nSamplesPerSec = sample : nAvgBytesPerSec = sample
            End Sub
        End Structure
     
        Private Structure WAVEHDR
            Dim lpData As IntPtr
            Dim dwBufferLength As Int32
            Dim dwBytesRecorded As Int32
            Dim dwUser As IntPtr
            Dim dwFlags As Int32
            Dim dwLoops As Int32
            Dim lpNext As IntPtr
            Dim reserved As IntPtr
            Sub New(ByVal sz As Int32)
                lpData = Marshal.AllocHGlobal(sz)
                dwBufferLength = sz
            End Sub
            Sub Free()
                Marshal.FreeHGlobal(lpData)
            End Sub
        End Structure
     
        Private Structure MyTag
            Dim hwav As IntPtr
            Dim hhdr As IntPtr
            Dim szhdr As Integer
        End Structure
     
        Private MT As MyTag
     
        Private Delegate Sub ProgrValDeleg(ByVal peakvol As Byte)
        Private Delegate Sub PtrwaveInProc(ByVal phwi As IntPtr, ByVal uMsg As Int32, ByVal dwInstance As Int32, ByVal dwParam1 As Int32, ByVal dwParam2 As Int32)
     
        Private Declare Function waveInOpen Lib "winmm" (ByRef phwi As IntPtr, ByVal uDeviceID As Int32, ByRef pwfx As WAVEFORMATEX, ByVal dwCallback As PtrwaveInProc, ByVal dwInstance As Int32, ByVal fdwOpen As Int32) As Int32
        Private Declare Function waveInClose Lib "winmm" (ByVal phwi As IntPtr) As Int32
        Private Declare Function waveInPrepareHeader Lib "winmm" (ByVal phwi As IntPtr, ByVal pwh As IntPtr, ByVal cbwh As Int32) As Int32
        Private Declare Function waveInUnprepareHeader Lib "winmm" (ByVal phwi As IntPtr, ByVal pwh As IntPtr, ByVal cbwh As Int32) As Int32
        Private Declare Function waveInAddBuffer Lib "winmm" (ByVal phwi As IntPtr, ByVal pwh As IntPtr, ByVal cbwh As Int32) As Int32
        Private Declare Function waveInStart Lib "winmm" (ByVal phwi As IntPtr) As Int32
        Private Declare Function waveInStop Lib "winmm" (ByVal phwi As IntPtr) As Int32
     
        Private Sub Form1_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.HandleCreated
            MicOpen()
        End Sub
     
        Private Sub Form1_HandleDestroyed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.HandleDestroyed
            MicClose()
        End Sub
     
        Private Sub MicOpen()
            MT.szhdr = Marshal.SizeOf(New WAVEHDR)
            MT.hhdr = Marshal.AllocHGlobal(MT.szhdr)
            Marshal.StructureToPtr(New WAVEHDR(512), MT.hhdr, False)
            waveInOpen(MT.hwav, -1, New WAVEFORMATEX(4096), AddressOf waveInProc, 0, CALLBACK_FUNCTION)
            waveInPrepareHeader(MT.hwav, MT.hhdr, MT.szhdr)
            waveInAddBuffer(MT.hwav, MT.hhdr, MT.szhdr)
            waveInStart(MT.hwav)
        End Sub
     
        Private Sub MicClose()
            Dim whdr As WAVEHDR = Marshal.PtrToStructure(MT.hhdr, GetType(WAVEHDR))
            waveInUnprepareHeader(MT.hwav, MT.hhdr, MT.szhdr)
            waveInStop(MT.hwav)
            waveInClose(MT.hwav)
            whdr.Free()
            Marshal.FreeHGlobal(MT.hhdr)
        End Sub
     
        Private Sub waveInProc(ByVal hwi As IntPtr, ByVal uMsg As Int32, ByVal dwInstance As Int32, ByVal dwParam1 As Int32, ByVal dwParam2 As Int32)
            If MM_WIM_DATA <> uMsg Then Return
            Dim whdr As WAVEHDR = Marshal.PtrToStructure(New IntPtr(dwParam1), GetType(WAVEHDR))
            Dim currvol As Integer, mastervol As Byte
            For i As Int32 = 0 To whdr.dwBytesRecorded - 1
                currvol = Math.Abs(Marshal.ReadByte(whdr.lpData, i)) - 127
                If (currvol > mastervol) Then mastervol = currvol
            Next
            On Error Resume Next
            Invoke(New ProgrValDeleg(AddressOf PeakMeterProc), New Object() {mastervol})' тут возникает делема
     
            waveInAddBuffer(hwi, New IntPtr(dwParam1), Marshal.SizeOf(whdr))
        End Sub
     
        Private Sub PeakMeterProc(ByVal peakvol As Byte)
            Static prgrsbar As New ProgressBar
            Controls.Add(prgrsbar)
            prgrsbar.Minimum = 0
            prgrsbar.Maximum = 16
            If peakvol < 5 Then peakvol = 0
            prgrsbar.Value = peakvol / 8
            'TextBox1.Text = (peakvol / 8)
        End Sub
     
    End Class

в последнем Sub PeakMeterProc я решил вывести визуально, помимо прогрессбара, текстовое поле со значением уровня
всё просто здорово, но...
но при простое выдает ошибку:
Был произведен обратный вызов делегата типа "WindowsApplication1!WindowsApplication1.Form1+PtrwaveInProc::Invoke", полученного сборщиком мусора. Это может привести к сбоям приложения, а также к повреждению или утрате данных. При передаче делегатов в неуправляемый код управляемое приложение должно поддерживать их существование, пока не будет гарантировано, что они больше никогда не будут вызваны.
TextBox1.Text = (mastervol).tostring пытался разместить в Private Sub waveInProc результат нулевой, как организовать получение уровня сигнала в постоянном - бесконечном прослушивание входа, советовали nAudio библиотеку но не одного вменяемого примера не нашел, любой вариант подойдет
умён и жаден,
характер отсуствует

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: слушатель уровня микрофона

Сообщение FireFenix » 13.05.2014 (Вт) 9:09

Где вопрос?

Так же очевидно, что это тема с сырцев перекочевала сюда, только зачем, если можно спросить там?

Вообще за такой аццкий код нужно по рукам бить!

Invader писал(а):Был произведен обратный вызов делегата типа "WindowsApplication1!WindowsApplication1.Form1+PtrwaveInProc::Invoke", полученного сборщиком мусора. Это может привести к сбоям приложения, а также к повреждению или утрате данных. При передаче делегатов в неуправляемый код управляемое приложение должно поддерживать их существование, пока не будет гарантировано, что они больше никогда не будут вызваны.

Установить английскую студию!

Invader писал(а):TextBox1.Text = (mastervol).tostring пытался разместить в Private Sub waveInProc результат нулевой

Ну естесно, а почему оно должно что-то давать? Тебе сказано совсем другое то
Invader писал(а):Был произведен обратный вызов делегата типа "WindowsApplication1!WindowsApplication1.Form1+PtrwaveInProc::Invoke", полученного сборщиком мусора


Invader писал(а):любой вариант подойдет

Писать осмысленно, отформатировать код, перестроить код так, чтоб все структуры были обьявлены глобально, которые используются в различных функциях как прямо так и косвенно.
Поучить P.Invoke, чтобы минимизировать ручной маршалинг.
Использовать отладчик!
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.05.2014 (Вт) 9:29

Ну русским языком же написано:
Invader писал(а):При передаче делегатов в неуправляемый код управляемое приложение должно поддерживать их существование, пока не будет гарантировано, что они больше никогда не будут вызваны.
Чего ещё не хватает?

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re:

Сообщение Invader » 13.05.2014 (Вт) 12:48

Qwertiy писал(а):Ну русским языком же написано:
Invader писал(а):При передаче делегатов в неуправляемый код управляемое приложение должно поддерживать их существование, пока не будет гарантировано, что они больше никогда не будут вызваны.
Чего ещё не хватает?

стабильности и моего понимания.
Попробую глобально...
умён и жаден,
характер отсуствует

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: слушатель уровня микрофона

Сообщение Invader » 13.05.2014 (Вт) 12:58

FireFenix писал(а):Где вопрос?
Так же очевидно, что это тема с сырцев перекочевала сюда, только зачем, если можно спросить там?

виноват, не внимателен

FireFenix писал(а):Установить английскую студию!

это поможет решению проблем?
умён и жаден,
характер отсуствует


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 32

    TopList