Hallo Forum ... Und mein erstes Problem

Anfängerfragen zum Programmieren mit PureBasic.
Backe
Beiträge: 4
Registriert: 21.10.2017 09:07
Computerausstattung: Windows 7, PB Vers. 4.61

Hallo Forum ... Und mein erstes Problem

Beitrag von Backe »

Hallo, ich habe mich eben neu angemeldet und wollte mich mal bedanken. Ich nutze das Forum schon längere Zeit, ohne Account, und fand eigentlich immer hilfreiche Tipps und Lösungsansätze, oder gar Beispiele. Also danke schon mal dafür :allright:

Nun habe ich aber ein Problem, zu dem ich nichts finden konnte:
Vor ein paar Monaten habe ich (aus dem englischen Forum) einen Codeschnipsel gefunden und daraus so etwas wie eine Visualiesierung programmiert. Diese Funktioniert auch Prima, wie ich finde. Jedoch... Es handelt sich um Prozeduren, die, mit Hilfe von WinAPI-Befehlen, auf das Mikrofon zugreifen. Also funktioniert meine Visualisierung zwar mit jedem mediaplayer, aber eben nur über das Mikrofon... wenn ich nun über das Headset Musik höre, geht das leider nicht. Meine Frage: Könnte sich Jemand, der sich mit WinAPI auskennt, den Code der Procedures anschauen und mir sagen, ob das nicht auch mit dem "AudioOut" funktionieren könnte? Achja! Erschwerend kommt noch dazu, dass ich diese Procedures nicht verstehe :oops: ich habe mir nur einen Wert davon abgegriffen, der die Lautstärke, der Geräusche, die durch das Mikrofon empfangen werden, in eine Zahl verwandelt..
Wenn es gewünscht wird, kann ich den kompletten Code irgendwo hochladen.

hier die Procedures:

Code: Alles auswählen

#SAMPLE_RATE   = 44100
#N_SAMPLES     = 8192 ;NUMBER OF SAMPLES

#WINDOW_WIDTH  = 1920 ;+ 300 ; full scale (5000) / resolution
#WINDOW_HEIGHT = 1080
#TRACE_COLOR   = $20DA42
#BACK_COLOR    = $004720
#GRID_COLOR    = 0
#Canvas        = 0
#Graticule     = 0 ; image



Structure MYWAVEFORMATEX
  wFormatTag.u ;UNSIGNED FOR COMPATIBILITY WITH MICROSOFT FLAG VALUES
  nChannels.w
  nSamplesPerSec.l
  nAvgBytesPerSec.l
  nBlockAlign.w
  wBitsPerSample.w
  cbSize.w
EndStructure

Global FFTWnd, smoothing, initSmoothing = #True

Structure CONFIG
  hWindow.i           ; Window handle
  size.i              ; Wave buffer size
  buffer.i            ; Wave buffer pointer
  wave.i              ; Address of waveform-audio input device
  format.MYWAVEFORMATEX ; Capturing WaveFormatEx
  lBuf.i              ; Capturing Buffer size
  nBuf.i              ; Capturing Buffer number
  nDev.i              ; Capturing Device identifier
  nBit.i              ; Capturing Resolution (8/16)
  nHertz.i            ; Capturing Frequency  (Hertz)
  nChannel.i          ; Capturing Channels number (Mono/Stereo)
  
EndStructure

Global Config.CONFIG
Global Dim inHdr.WAVEHDR(16)

Config\format\wFormatTag = #WAVE_FORMAT_PCM

Procedure CAPTURE_START()
  Config\format\nChannels=1
  Config\format\wBitsPerSample = 16
  Config\format\nSamplesPerSec = #SAMPLE_RATE
  Config\nDev = 0 ; (default MS Sound Mapper device)
  Config\lBuf = #N_SAMPLES
  Config\nBuf = 8
  Config\nBit = 1
  
  Config\format\nBlockAlign = (Config\format\nChannels * Config\format\wBitsPerSample)/8
  Config\format\nAvgBytesPerSec = Config\format\nSamplesPerSec * Config\format\nBlockAlign
  
  If #MMSYSERR_NOERROR = waveInOpen_(@Config\wave, #WAVE_MAPPER+Config\nDev, @Config\format,Config\hWindow, #Null, #CALLBACK_WINDOW | #WAVE_FORMAT_DIRECT)
    
    
    For i=0 To Config\nBuf-1
      inHdr(i)\lpData=AllocateMemory(Config\lBuf)
      inHdr(i)\dwBufferLength=Config\lBuf
      waveInPrepareHeader_(Config\wave, inHdr(i), SizeOf(WAVEHDR))
      waveInAddBuffer_(Config\wave, inHdr(i), SizeOf(WAVEHDR))
    Next
    
    waveInStart_(Config\wave)
    
  EndIf
  
EndProcedure


EnableExplicit
Procedure COMPLEX_FFT()
  ; http://paulbourke.net/miscellaneous/dft/
  ; Appendix B. FFT (Fast Fourier Transform)
  ; This computes an in-place complex-To-complex FFT
  ; Real And Imag are the real And imaginary arrays of 2^m points.
  
  Static Dim Real.d(#N_SAMPLES)
  Static Dim Imag.d(#N_SAMPLES)
  Static Dim SmSum(#WINDOW_WIDTH-1)
  Static Dim Sm_Buff(#WINDOW_WIDTH-1,31) ; max smoothing = 32
  Static SmIDX = 0
  Static NM1 = #N_SAMPLES - 1
  Static ND2 = #N_SAMPLES >> 1
  Static Hscale.f = 0.0 + (#SAMPLE_RATE / #N_SAMPLES)
  Global Ergebnis.f
  
  
  Protected mask = smoothing - 1
  ;Protected M = Int(Log(#N_SAMPLES) / Log(2))
  Protected.i M = Int(Log(#N_SAMPLES) / 0.69314718055994529)
  Protected.i i, IP, j, k, n, LE2, LE, Imax, y, Ly, peak_Y, peak_X
  Protected.d C1, C2, TR, TI, UR, UI, ZZ
  
  If initSmoothing : initSmoothing = #False
    i = 0 ; init smoothing buffers
    While i < #WINDOW_WIDTH : k = 0
      While k < smoothing : Sm_Buff(i,k) = #WINDOW_HEIGHT : k + 1 : Wend
      SmSum(i) = #WINDOW_HEIGHT * smoothing
      i + 1
    Wend
  EndIf
  
  ; -------- Clear and Fill array values for analyzing --------
  i = 0 : j = ND2 : k = 0
  While k < Config\size
    Real(i) = PeekW(Config\buffer + k) ; 0 to SAMPLES/2 - 1
    Imag(i) = 0        ; 0 to SAMPLES/2 - 1
    Real(j) = 0        ; SAMPLES/2 to SAMPLES
    Imag(j) = 0        ; SAMPLES/2 to SAMPLES
    i + 1 : j + 1 : k + 2
  Wend
  
  j = 0
  Imax = #N_SAMPLES - 2
  
  For i = 0 To Imax  ; Gold-Rader bit reversal algorithm
    If i < j
      Swap Real(i),Real(j)
      ;Swap Imag(i), Imag(j) ; both are zero
    EndIf
    k = ND2
    While k <= j
      j = j - k
      k = k >> 1
    Wend
    j = j + k
  Next
  
  

  
  ; Compute the FFT
  C1 = -1.0
  C2 = 0.0
  LE = 1
  
  For n = 1 To M
    LE2 = LE
    LE << 1
    UR = 1.0
    UI = 0.0
    
    k = 0
    While k < LE2 : i = k
      While i < #N_SAMPLES ; Loop for each butterfly calculation
        IP = i + LE2
        TR = Real(IP) * UR - Imag(IP) * UI
        TI = Imag(IP) * UR + Real(IP) * UI
        Real(IP) = Real(i) - TR
        Imag(IP) = Imag(i) - TI
        Real(i) + TR
        Imag(i) + TI
        i + LE
      Wend
      
      ZZ = UR * c1 - UI * C2
      UI = UR * c2 + UI * C1
      UR = ZZ
      k + 1
    Wend
    
    C2 = Sqr((1.0 - C1) / 2.0)
    C1 = Sqr((1.0 + C1) / 2.0)
  Next n
  
  For i = 0 To NM1 ; Scaling For forward transform
    Real(i) = Abs(Real(i) / #N_SAMPLES)
    ;Imag(i) = Abs(Imag(i) / #N_SAMPLES) ; we don't use this
  Next
  
  
  
  Ly = #WINDOW_HEIGHT
  
  i = 0 : peak_Y = #WINDOW_HEIGHT
  While i < #WINDOW_WIDTH
    y = #WINDOW_HEIGHT - Log(Real(i)+1) * 64 ; 64 is arbitrary
    If smoothing
      SmSum(i) - Sm_Buff(i,SmIDX)
      Sm_Buff(i,SmIDX) = y
      SmSum(i) + y
      y = SmSum(i) / smoothing ; this is the moving average
      
    EndIf
    
    ;          LineXY(i-1,Ly,i,y,#TRACE_COLOR) : Ly = y
    
    If y < peak_Y : peak_Y = y : peak_X = i : EndIf
    i + 1
  Wend
  
  ;       Circle(peak_X, peak_Y, 3, #Red)
  Ergebnis = peak_X * Hscale;+" Hz"
  
  If smoothing : SmIDX = (SmIDX + 1) & mask : EndIf
  ;   StopDrawing()
  
  ProcedureReturn #True
EndProcedure
DisableExplicit


Procedure CAPTURE_CALLBACK(hWnd.i, Msg.i, wParam.i, lParam.i)
  If Msg = #MM_WIM_DATA
    *hWave.WAVEHDR = lParam
    Config\buffer = *hWave\lpData
    Config\size = *hWave\dwBytesRecorded
    waveInAddBuffer_(wParam, *hWave, SizeOf(WAVEHDR))
    
    COMPLEX_FFT()
  EndIf
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Hallo Forum ... Und mein erstes Problem

Beitrag von Sicro »

Willkommen Backe :)

Unter welcher Windows-Version arbeitest du?

Hast du den Stereomix unter deinem Windows aktiviert?
Mit diesem lassen sich Töne aufnehmen, die aus den Lautsprechern ertönen.
Stereomix aktivieren unter Windows 10: https://www.youtube.com/watch?v=OOxQ1WxKjP0
Probiere dein Code nach der Aktivierung von Stereomix erneut aus.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Backe
Beiträge: 4
Registriert: 21.10.2017 09:07
Computerausstattung: Windows 7, PB Vers. 4.61

Re: Hallo Forum ... Und mein erstes Problem

Beitrag von Backe »

Wow, vielen Dank! Das funktioniert super (sogar unter Windows7 ;)) und ist einfacher, als gedacht :O
Kann ich über PureBasic (wahrscheinlich eher WinAPI) herausfinden, ob ein Mikrofon eingesteckt ist, bzw als Standartgerät aktiviert ist und dies dann auch ändern? Also, dass ich am Anfang checke, ob Stereomix aktiv ist, wenn nicht, dieses aktiviere und beim Schließen meines Codes wieder zurücksetze.
Backe
Beiträge: 4
Registriert: 21.10.2017 09:07
Computerausstattung: Windows 7, PB Vers. 4.61

Re: Hallo Forum ... Und mein erstes Problem

Beitrag von Backe »

Also ich habe es jetzt so gelöst, dass ich mit Hilfe von waveInGetNumDevs_ die Anzahl der verfügbaren Waveform-Audio-Input-Geräte ermittle.
Dann habe ich in der CAPTURE_START() Procedure Dies: Config\nDev = 0 in dies: Config\nDev = Dev verwandelt. Und dann verändere ich mit den Pfeiltasten die Dev-Variable, passe auf, dass sie nicht größer als waveInGetNumDevs_ wird, anschließend die CAPTURE_START() Procedure wieder aufrufen und das geht.
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Hallo Forum ... Und mein erstes Problem

Beitrag von Sicro »

Ich weiß, wir sind hier im Anfänger-Unterforum, aber vielleicht kommst du trotzdem damit klar:
https://github.com/SicroAtGit/PureBasic ... T%5BWin%5D

Die Module in dem Verzeichnis "Includes" vereinfachen die Sound-Funktionen.

Der Code "Example_Plot.pb" kommt deinem Vorhaben ziemlich nahe. Dort werden die Eingangstöne grafisch dargestellt. Zudem werden die Namen der Devices als Debug-Ausgabe ausgegeben.

Schaut man sich den Code "Example_Plot.pb" und den Code "Includes/AudioIN.pbi" an, ist zu erkennen, dass nur "#WAVE_MAPPER" an die Win-API "waveInOpen_()" übergeben wird und nicht "#WAVE_MAPPER+Config\nDev", wie du es machst.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Backe
Beiträge: 4
Registriert: 21.10.2017 09:07
Computerausstattung: Windows 7, PB Vers. 4.61

Re: Hallo Forum ... Und mein erstes Problem

Beitrag von Backe »

Danke für deine Mühen :allright:
Aber das ist eigentlich ein Projekt, was wahrscheinlich eh nur ich nutze.. und so genügt mir die Anwenderfreundlichkeit :)
Falls sich Jemand das Spektakel anschauen möchte: https://www.dropbox.com/sh/tiu1jbcd4u1r ... Z6I2a?dl=0
:wink:
Antworten