Probleme mit Mikrofoncode

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Probleme mit Mikrofoncode

Beitrag von Chimorin »

Heyho,
ich habe vor einiger Zeit ja einen Code zum Mikrofondatenabfang hier gepostet. http://www.purebasic.fr/german/viewtopi ... =8&t=28432
Nun wollte ich das Ganze ein wenig umschreiben und daraus ein Modul machen. Funktioniert auch soweit so gut.
Leider sind von den 8 Datenpaketen 7 leer, was ich nicht verstehe. Diese 7 werden aber gebraucht, sonst ist die Audiospur viel zu schnell.
Eventuell kennt sich da jemand aus oder kann mir sonst helfen, evtl. ist es ja auch nur ein einfacher Fehler im Code:

Code: Alles auswählen

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>                             >>
;>>  Name: AudioIN              >>
;>>                             >>
;>>  Author: (c) Chimorin       >>
;>>             (Bananenfreak)  >>
;>>                             >>
;>>  Date: 05.10.2014           >>
;>>                             >>
;>>  OS: Windows                >>
;>>                             >>
;>>                             >>
;>>                             >>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EnableExplicit


Define.f KeyX, KeyY, MouseX, MouseY
Define nx.f, nz.f, Boost.f = 1, Yaw.f, Pitch.f
Define.i Quit, sound, file
#kam_0 = 0
#window = 0


DeclareModule AudioIn
  EnableExplicit
  
  Structure rec
    buffer.i
    size.i
  EndStructure
  
  #BUFFER_NUM = 8         ; Number of buffer for capture 
  
  Global NewList devices.WAVEINCAPS()
  Global NewList audio.rec()
  Global Dim inHdr.WAVEHDR(#BUFFER_NUM-1)
  
  Declare GetDevices()
  Declare Start()
  ;Declare ARead()
EndDeclareModule


Module AudioIn
  Global.i inputZgr       ;Ist das Handle des geöffneten Inputdevice
  
  #SOUND_NCHANNELS = 1    ;Anzahl der Kanäle: 1 = Mono
  #SOUND_NBITS = 16       ;Bittiefe des Audiodings, hier 16bit
  #SOUND_NHERTZ = 44100   ;Hertzanzahl. 
  #BUFFER_SIZE = 512      ; Size of each buffer, should be x2 in Stereo 
  
  
  Declare Error(err.i)
  
  
  Procedure Stop()        ;Stoppt die Aufnahme und freet alles.
  Protected.i i
  
  
  If inputZgr
    Error(waveInReset_(inputZgr))       ;Die Funktion waveInReset stoppt Input auf der vorhandenen Wave-Audio-Eingabegerät und setzt die aktuelle Position auf Null (zurück). Alle ausstehenden Puffer sind  als erledigt markiert und werden zur Anwendung "zurückgeschickt".
    Error(waveInStop_(inputZgr))        ;Die Funktion waveInStop stoppt Wave-Audio input.
    For i = 0 To #BUFFER_NUM - 1 
      Error(waveInUnprepareHeader_(inputZgr, inHdr(i), SizeOf(WAVEHDR)))        ;Diese Funktion bereinigt die Vorbereitung durch waveInPrepareHeader durchgeführt. Die Funktion muss aufgerufen werden, nachdem die Gerätetreiber füllt einen Datenpuffer und gibt sie an die Anwendung. Sie müssen diese Funktion vor der Befreiung der Datenpuffer nennen.
    Next 
    Error(waveInClose_(inputZgr))       ;Diese Funktion schließt die angegebene wave-Audio-Eingabegerät.
  EndIf
  EndProcedure
  
  
  Procedure Error(err.i)        ;Wirft den Fehler aus, der zu diesem Ding gehört.
    Protected.s text
    
    
    If err 
      text = Space(#MAXERRORLENGTH) 
      waveInGetErrorText_(err, text, #MAXERRORLENGTH)       ;Diese Funktion ruft eine Textbeschreibung des von der angegebenen Fehlernummer identifiziert Fehler.
      MessageRequester("Error", text, #MB_ICONERROR)
      Stop() 
      End 
    EndIf 
  EndProcedure
  
  
  Procedure GetDevices()       ;Listet die vorhandenen Audioeingänge auf und gibt den Namen Eines zurück.
    Protected.i size, zaehler
    
    size = waveInGetNumDevs_()
    FirstElement(devices())
    For zaehler = 0 To size -1        ;Die waveInGetNumDevs Funktion gibt die Anzahl der Wellenform-Audio-Eingang im System vorhandenen Geräte.
      AddElement(devices())
      Error(waveInGetDevCaps_(zaehler, devices(), SizeOf(WAVEINCAPS)))       ;Die waveInGetDevCaps Funktion ruft die Fähigkeiten eines gegebenen Wellenform-Audioeingabegerät.
      If Not Bool(devices()\dwFormats & #WAVE_FORMAT_4M16)                   ;dwFormats ist eine Addition aller unterstützter Audioformate (Siehe Anhang 1)
        DeleteElement(devices())
      EndIf
    Next 
  EndProcedure 
  
  
  Procedure ARead(wParam.i)
    Protected.i buffer, size
    
    
    Error(waveInAddBuffer_(inputZgr, wParam, SizeOf(WAVEHDR)))
    ;Debug PeekS(wParam)
    buffer = PeekL(wParam)
    ;Debug buffer
    ;Debug PeekL(buffer)
    ;Debug "000000000000000000"
    
    ;If Not buffer = 0
      ;Debug ".........."
      LastElement(audio())
      AddElement(audio())
      audio()\buffer = buffer;PeekL(buffer)
      audio()\size = PeekL(wParam + 8)
    ;Else
      ;Debug "Buffer ist 0, warum?"
    ;EndIf
  EndProcedure
  
  
  Procedure CallBack(hWnd.i, uMsg.i, instance.i, wParam.i, lParam.i)        ;Callbackfunktion für alle Inputevents. hWnd: inputZgr | instance ist nur vorhanden, wenn bei waveInOpen_() dwInstance angegeben wurde.
    Debug hWnd
    Debug uMsg
    Debug "i:" + instance
    Debug "w" + wParam
    Debug "l:" + lParam
    Debug "--------------------"
    Select uMsg 
      Case #WIM_DATA
        If hWnd = inputZgr
          ARead(wParam)
          
        Else
          Debug "Da ist was anderes im Busch!"
          
        EndIf
        
      Case #WIM_OPEN
        Debug "Open"
        
      Case #WIM_CLOSE
        Debug "Close"
    EndSelect
  EndProcedure
  
  
  Procedure Start()       ;Initialisierungszeug.
    Protected.WAVEFORMATEX format   ;format.WAVEFORMATEX übergibt in waveInOpen_() Infos über das angeforderte Audiomaterial.
    Protected.i zaehler
    
    
    format\wFormatTag      = 1        ;#WAVE_FORMAT_PCM? Ist es das?
    format\nChannels       = #SOUND_NCHANNELS
    format\wBitsPerSample  = #SOUND_NBITS
    format\nSamplesPerSec  = #SOUND_NHERTZ
    format\nBlockAlign     = #SOUND_NCHANNELS * (#SOUND_NBITS/8)
    format\nAvgBytesPerSec = #SOUND_NHERTZ * format\nBlockAlign
    format\cbSize          = 0
    Error(waveInOpen_(@inputZgr, #WAVE_MAPPER, @format, @CallBack(), 13, #CALLBACK_FUNCTION|#WAVE_FORMAT_DIRECT))        ;Öffnet das spezifische Waveinputdevice.
    
    For zaehler = 0 To #BUFFER_NUM -1
      inHdr(zaehler)\lpData         = AllocateMemory(#BUFFER_SIZE) 
      inHdr(zaehler)\dwBufferLength = #BUFFER_SIZE
      Error(waveInPrepareHeader_(inputZgr, inHdr(zaehler), SizeOf(WAVEHDR)))        ;Diese Funktion erstellt einen Puffer für wave-input. Diese Funktion ermöglicht dem Audiotreiber und dem Betriebssystem (OS) zu Zeit raubende Verarbeitung des Kopf-und / oder Puffer einmal bei der Initialisierung. Die Anwendung kann die Puffer wiederholt ohne zusätzliche Verarbeitungs Nutzung durch den Fahrer oder das Betriebssystem.
      Error(waveInAddBuffer_(inputZgr, inHdr(zaehler), SizeOf(WAVEHDR)))            ;Die waveInAddBuffer Funktion sendet einen inputpuffer, an das gegebene Wave-Audioeingabegerät. Wenn der Puffer voll ist, wird die Anwendung informiert.
    Next zaehler
    
    Error(waveInStart_(inputZgr))        ;Diese Funktion startet input auf dem angegebenen wave-Eingabegerät.
  EndProcedure
EndModule


InitSprite()
InitKeyboard()
InitSound()

OpenWindow(#window, 0, 0, 1800, 1000, "AudioIn-Out Test", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#window), 10, 10, 2000, 2000, 0, 10, 10, #PB_Screen_SmartSynchronization)

;SetWindowCallback(@CallBack())

AudioIn::GetDevices()
; ForEach AudioIn::devices()
;   Debug PeekS(AudioIn::@devices()\szPname)
; Next
AudioIn::Start()

file = CreateFile(#PB_Any, "D:\test.raw")

Repeat
  Repeat
  Until WindowEvent() = 0
  
  If ExamineKeyboard()
    
  EndIf
  
  If ListSize(AudioIn::audio())
    WriteData(file, AudioIn::audio()\buffer, AudioIn::audio()\size)
    DeleteElement(AudioIn::audio())
;     If IsSound(sound)
;       Select SoundStatus(sound)
;         Case #PB_Sound_Stopped
;           Debug "1"
;           FirstElement(AudioIn::audio())
;           ;sound = CatchSound(#PB_Any, AudioIn::audio()\buffer, AudioIn::audio()\size)
;           ;PlaySound(sound)
;           DeleteElement(AudioIn::audio())
;           
;       EndSelect
;       
;     Else
;       Debug "2"
;       FirstElement(AudioIn::audio())
;       Debug "Buffer:" + AudioIn::audio()\buffer
;       sound = CatchSound(#PB_Any, AudioIn::audio()\buffer)
;       Debug sound
;       ;PlaySound(sound)
;       DeleteElement(AudioIn::audio())
;     EndIf
  EndIf
  
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

CloseFile(file)
End
Zuletzt geändert von Chimorin am 11.10.2014 19:18, insgesamt 1-mal geändert.
Bild

- formerly known as Bananenfreak -
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: Probleme mit Mikrofoncode

Beitrag von Chimorin »

Da waren i´s als zaehler drin, jetzt kommen 8 buffer an, aber das Ganze ist dennoch viel zu schnell (8-fache Geschwindigkeit).
Ich habe nicht viel Ahnung von Soundzeug. Was muss ich machen? ;D

Wenn man mal nicht mehr auf dem Schlauch steht, läuft es flüssig. Problem behoben. Es lag einfach daran, dass die Liste mit den Codeschnipseln nicht abgearbeitet wurde. So, fertig. Den Code kann man nun bestaunen: http://www.purebasic.fr/german/viewtopi ... =8&t=28447
Bild

- formerly known as Bananenfreak -
Antworten