How to record audio from line-in microphone?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

How to record audio from line-in microphone?

Post by Psychophanta »

Is there a way to record audio from line-in microphone using PB?
I am not able to find a native lib with a function to do this...
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: How to record audio from line-in microphone?

Post by Simo_na »

no FFT
no ASIO

in the Age of Multimedia, the advanced audio control are in the 'Stone Age Modality'...here. :mrgreen:
morosh
Enthusiast
Enthusiast
Posts: 293
Joined: Wed Aug 03, 2011 4:52 am
Location: Beirut, Lebanon

Re: How to record audio from line-in microphone?

Post by morosh »

for windows, using mci:

Code: Select all

filename.s = "C:\Users\xxx\Desktop\testing.wav"
Procedure RecordWave(Filename.s,RecordTime)
RS.s = Space(128)
DeleteFile(filename)
i = mciSendString_("open new type waveaudio alias capture", RS, 128, cb)
i = mciSendString_("record capture", RS, 128, cb)
Delay(RecordTime)
i = mciSendString_("save capture " + filename, RS, 128, cb)
EndProcedure

MessageRequester("Info","Capture Audio to C:\Users\xxx\Desktop\test.wav",0)
RecordWave("C:\Users\xxx\Desktop\test.wav",2000)
MessageRequester("Info","Ready...",0)
HTH
PureBasic: Surprisingly simple, diabolically powerful
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: How to record audio from line-in microphone?

Post by Psychophanta »

Thank you very much Morosh. :wink:
Useful.

Anyway there is objetively curious and a notable incoherence the fact that in the native "sound" PB lib there are Functions for output audio sequences, but there are not any function to input audio sequences. :shock:
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: How to record audio from line-in microphone?

Post by Simo_na »

morosh wrote:for windows, using mci:

HTH
but excuse, without able to adjust the microphone input gain ... what comes out ?? :x
User avatar
Dadido3
User
User
Posts: 52
Joined: Sat Jan 12, 2008 11:50 pm
Location: Hessen, Germany
Contact:

Re: How to record audio from line-in microphone?

Post by Dadido3 »

Hi,

you could also use my module for audio recording and playback.

The newest version is available here: https://github.com/Dadido3/Audio.
You just have to download the zip, it contains the includes and some examples.

A simple way to capture data and plot it into the console looks like this:

Code: Select all

XIncludeFile "Includes/AudioIn.pbi"

OpenConsole()

PrintN("Devices:")
AudioIn::GetDevices()
ForEach AudioIn::Device()
 PrintN(PeekS(AudioIn::@Device()\szPname))
Next
PrintN("")

*AudioIn = AudioIn::Initialize(#WAVE_MAPPER, 44100, 1, 8)

If Not *AudioIn
  PrintN("Error: " + AudioIn::GetError())
  Input()
  End
EndIf

PrintN("Press enter to start recording")
Input()
AudioIn::Start(*AudioIn)

*Temp = AllocateMemory(10)

Repeat
  If AudioIn::GetAvailableData(*AudioIn) >= 10
    
    If AudioIn::Read_Data(*AudioIn, *Temp, 10) >= 0
      PrintN(LSet("", PeekA(*Temp)/2, " ")+"#") ; #### Only draw the first byte of the 10 byte buffer
    Else
      PrintN(AudioIn::GetError())
    EndIf
    
  EndIf
Until Inkey()

FreeMemory(*Temp)

AudioIn::Deinitialize(*AudioIn)
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: How to record audio from line-in microphone?

Post by dobro »

Flype Code :

Code: Select all

;/ Object     MME Audio Recorder 1.0 (a)
;/
;/ Date       August 2004
;/ Author     Philippe Carpentier
;/ Contact    flype@altern.org
;/ Info       MS Windows only - MME, winmm.lib - mmsystem.h

;  Bug fixes by chris319 on September 2, 2007
;  04/02/2010 : DrGolf for PB 4.50
;  01/20/2011 : Vitor_Boss® -- Fixed clamping
;  06/10/2012 : Multi-threaded version by chris319 on PB 4.61

;- REC CONSTANTES
    ;
#MinWidth      = 640
#MinHeight     = 480

#MONO = 1
#STEREO = 2

;- REC INITIALISATION

Enumeration 0 ; #CHANNEL
  #CHANNEL_LEFT
  #CHANNEL_RIGHT
EndEnumeration

Enumeration 0 ; #GADGET
  #gadFrame1
  #gadFrame2
  #gadStart
  #gadStop
  #gadSndVol
  #gadFile
  #gadChannel
  #gadFrequence
  #gadDevice
  #gadText1
  #gadText2
EndEnumeration

Enumeration 0 ; #WINDOW
  #Window
EndEnumeration

Enumeration 0 ; #TOOLBAR
  #ToolBar
EndEnumeration

Enumeration 0 ; #STATUS BAR
  #StatusBar
EndEnumeration

;Structure WAVEFORMATEX -- NOT NEEDED IN PB 4.10 -- chris319
;  wFormatTag.w
;  nChannels.w
;  nSamplesPerSec.l
;  nAvgBytesPerSec.l
;  nBlockAlign.w
;  wBitsPerSample.w
;  cbSize.w
;EndStructure

Structure SCOPE
  channel.b
  left.l
  top.l
  width.l
  height.l
  middleY.l
  quarterY.l
EndStructure

Structure CONFIG
     
      hWindow.l           ; Window handle
      hToolBar.l          ; ToolBar handle
      hfont.l             ; Font handle
     
      Date.l              ; Start date
      size.l              ; Wave buffer size
      buffer.l            ; Wave buffer pointer
      output.l            ; WindowOutput()
      wave.l              ; Address of waveform-audio input device
      recorded.l          ; Number of bytes recorded
      recording.b         ; Record is running...
     
      File.s              ; Recording FileName (c:\unnamed.snd) ;chris319 6/7/12
      FileId.l            ; Recording FileId (#PB_Any)
      SndVol.s            ; Microsoft Volume Control (sndvol32.exe)

      format.WAVEFORMATEX ; Capturing WaveFormatEx
      lBuf.l              ; Capturing Buffer size
      nBuf.l              ; Capturing Buffer number
      nDev.l              ; Capturing Device identifier
     
      LScope.SCOPE        ; Wave form display
      RScope.SCOPE        ; Wave form display
      ScopeTimer.l        ; Scope Timer (redraw every n times)
      cback.l             ; Back color
      cline.l             ; Line color
      cwave.l             ; Wave color
      ColRecWave.l        ; Scope Record Wave Color
      ColRecBack.l        ; Scope Record Back Color
      ColRecLine.l        ; Scope Record Line Color
      ColCapWave.l        ; Scope Capture Wave Color
      ColCapBack.l        ; Scope Capture Back Color
      ColCapLine.l        ; Scope Capture Line Color
     
    EndStructure

;- GLOBAL
Global Config.CONFIG, threadID1, threadID2
;*hWave.WAVEHDR
Global Dim inHdr.WAVEHDR(16), QuitRec.l, audioSemaphore, meterSemaphore, wpa, lpa, *meterBuffer, *audioBuffer
   ;
    Config\hfont             = LoadFont(0,"Arial",7)
    Config\format\cbSize     = 0
    Config\format\wFormatTag = #WAVE_FORMAT_PCM
    Config\LScope\channel    = #CHANNEL_LEFT
    Config\RScope\channel    = #CHANNEL_RIGHT
    ;
;- REC DECLARATIONS
    ;
Declare CONFIG_Load()
Declare CONFIG_Save()

Declare CAPTURE_Stop()
Declare CAPTURE_Start()
Declare CAPTURE_Error(err.l)
Declare CAPTURE_GetDevices(gadId.l)
Declare CAPTURE_Read(hWaveIn.l,lpWaveHdr.l)

Declare FILE_Close()
Declare FILE_Append()
Declare FILE_Create()
Declare FILE_Select()
Declare FILE_Recording(state.b)
Declare FILE_raw2wav(File.s)

Declare GUI_Init()
Declare GUI_Resize()
Declare GUI_TBCombo(Id,x,y,w,h)
Declare GUI_CallBack(hWnd.l,Msg.l,wParam.l,lParam.l)

;- REC PROCEDURES
    ;
    Procedure CONFIG_Load()
     
      OpenPreferences("Recorder.ini")
     
      PreferenceGroup("Files")
      Config\File   = ReadPreferenceString("FileName","c:\unnamed.snd")
      Config\SndVol = ReadPreferenceString("SndVol","sndvol32")
     
      PreferenceGroup("Capture")
      Config\nDev     = ReadPreferenceLong("Device",0)
      Config\format\nChannels = ReadPreferenceLong("Channel", 1)
      Config\format\nSamplesPerSec   = ReadPreferenceLong("Frequency",44100)
      Config\format\wBitsPerSample = 16
      Config\nBuf = 8 ;ReadPreferenceLong("BufferNum",8) ;chris319 6/7/12
      Config\lBuf = 8192 ;ReadPreferenceLong("BufferLen", 2048) ;chris319

      PreferenceGroup("Scope")
      Config\ScopeTimer   = 20
      Config\ColRecLine   = ReadPreferenceLong("ColRecLine",  $000035)
      Config\ColRecWave   = ReadPreferenceLong("ColRecWave",  $1010E0)
      Config\ColRecBack   = ReadPreferenceLong("ColRecBack",  $000050)
      Config\ColCapLine   = ReadPreferenceLong("ColCapLine",  $004000)
      Config\ColCapWave   = ReadPreferenceLong("ColCapWave",  $20E020)
      Config\ColCapBack   = ReadPreferenceLong("ColCapBack",  $004900)
     
      PreferenceGroup("Window")
      pos.WINDOWPLACEMENT
      pos\length=SizeOf(WINDOWPLACEMENT)
      pos\ptMinPosition\x         = ReadPreferenceLong("MinPosX",0)
      pos\ptMinPosition\y         = ReadPreferenceLong("MinPoxY",0)
      pos\ptMaxPosition\x         = ReadPreferenceLong("MaxPosX",-1)
      pos\ptMaxPosition\y         = ReadPreferenceLong("MaxPosY",-1)
      pos\rcNormalPosition\left   = ReadPreferenceLong("PosX1",100)
      pos\rcNormalPosition\top    = ReadPreferenceLong("PosY1",100)
      pos\rcNormalPosition\right  = ReadPreferenceLong("PosX2",#MinWidth)
      pos\rcNormalPosition\bottom = ReadPreferenceLong("PosY2",#MinHeight)
     
      ClosePreferences()
     
      Config\cback   = Config\ColCapBack
      Config\cline   = Config\ColCapLine
      Config\cwave   = Config\ColCapWave
     
      StatusBarText(0,2,Config\File)
      SetGadgetState(#gadDevice,Config\nDev)
      SetGadgetState(#gadChannel,Config\format\nChannels - 1)

;      SetGadgetState(#gadFrequence,Config\format\nSamplesPerSec)
Select Config\format\nSamplesPerSec ;chris319 6/7/12
  Case  8000: SetGadgetState(#gadFrequence, 0)
  Case 11025: SetGadgetState(#gadFrequence, 1)
  Case 12000: SetGadgetState(#gadFrequence, 2)
  Case 16000: SetGadgetState(#gadFrequence, 3)
  Case 22050: SetGadgetState(#gadFrequence, 4)
  Case 24000: SetGadgetState(#gadFrequence, 5)
  Case 32000: SetGadgetState(#gadFrequence, 6)
  Case 44100: SetGadgetState(#gadFrequence, 7)
  Case 48000: SetGadgetState(#gadFrequence, 8)
EndSelect

;SetWindowPlacement_(Config\hWindow,@pos)
;ShowWindow_(Config\hWindow,#True)
     
    EndProcedure
    ;
    Procedure CONFIG_Save()
     
pos.WINDOWPLACEMENT
pos\length = SizeOf(WINDOWPLACEMENT)
GetWindowPlacement_(Config\hWindow,@pos)
     
If CreatePreferences("Recorder.ini")
 
  PreferenceGroup("Files")
  WritePreferenceString("FileName",Config\File)
  WritePreferenceString("SndVol",Config\SndVol)
 
  PreferenceGroup("Capture")
  WritePreferenceLong("Device",Config\nDev)
  WritePreferenceLong("Channel",Config\format\nChannels)
  WritePreferenceLong("Frequency",Config\format\nSamplesPerSec)
 
  PreferenceGroup("Scope")
  WritePreferenceLong("ColRecLine",Config\ColRecLine)
  WritePreferenceLong("ColRecWave",Config\ColRecWave)
  WritePreferenceLong("ColRecBack",Config\ColRecBack)
  WritePreferenceLong("ColCapLine",Config\ColCapLine)
  WritePreferenceLong("ColCapWave",Config\ColCapWave)
  WritePreferenceLong("ColCapBack",Config\ColCapBack)
 
  PreferenceGroup("Window")
  WritePreferenceLong("MinPosX",pos\ptMinPosition\x)
  WritePreferenceLong("MinPoxY",pos\ptMinPosition\y)
  WritePreferenceLong("MaxPosX",pos\ptMaxPosition\x)
  WritePreferenceLong("MaxPosY",pos\ptMaxPosition\y)
  WritePreferenceLong("PosX1",pos\rcNormalPosition\left)
  WritePreferenceLong("PosY1",pos\rcNormalPosition\top)
  WritePreferenceLong("PosX2",pos\rcNormalPosition\right)
  WritePreferenceLong("PosY2",pos\rcNormalPosition\bottom)
 
  ClosePreferences()
  ProcedureReturn #True
 
EndIf
     
    EndProcedure
    ;
    Procedure CAPTURE_Error(err.l)

      If err
        text.s=Space(#MAXERRORLENGTH)
        waveInGetErrorText_(err,text,#MAXERRORLENGTH)
        MessageRequester("Error",text,#MB_ICONERROR)
        CAPTURE_Stop()
        End
      EndIf

    EndProcedure
    ;
Procedure CAPTURE_Start()
     
      CAPTURE_Stop()

;GET USER SETTINGS     
      Config\nDev = GetGadgetState(#gadDevice)
     
;      Config\format\nChannels = ;chris319 6/7/12
      state = GetGadgetState(#gadChannel)
      Select state
        Case 0 : Config\format\nChannels = #MONO
        Case 1 : Config\format\nChannels = #STEREO
      EndSelect
      gui_Resize() ;chris319 6/7/12

;      Config\format\nSamplesPerSec ;chris319 6/7/12
      state = GetGadgetState(#gadFrequence)
      Select state
        Case 0 : Config\format\nSamplesPerSec =  8000
        Case 1 : Config\format\nSamplesPerSec = 11025
        Case 2 : Config\format\nSamplesPerSec = 12000
        Case 3 : Config\format\nSamplesPerSec = 16000
        Case 4 : Config\format\nSamplesPerSec = 22050
        Case 5 : Config\format\nSamplesPerSec = 24000
        Case 6 : Config\format\nSamplesPerSec = 32000
        Case 7 : Config\format\nSamplesPerSec = 44100
        Case 8 : Config\format\nSamplesPerSec = 48000
      EndSelect

  Config\format\nBlockAlign = (Config\format\nChannels * Config\format\wBitsPerSample) / 8
  Config\format\nAvgBytesPerSec = Config\format\nSamplesPerSec * Config\format\nBlockAlign
  Config\format\cbSize = 0
   
      If #MMSYSERR_NOERROR = waveInOpen_(@Config\wave,#WAVE_MAPPER+Config\nDev,@Config\format,Config\hWindow,#Null,#CALLBACK_WINDOW|#WAVE_FORMAT_DIRECT)
        For i = 0 To 7
          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)

        If #MMSYSERR_NOERROR = waveInStart_(Config\wave)
          SetTimer_(Config\hWindow,0,Config\ScopeTimer,0)
        EndIf

      EndIf

If IsThread(threadID1) <> 0
  ResumeThread(threadID1)
EndIf
If IsThread(threadID2) <> 0
  ResumeThread(threadID2)
EndIf

EndProcedure
    ;
Procedure CAPTURE_Stop()
If IsThread(threadID1) <> 0
  PauseThread(threadID1)
EndIf
If IsThread(threadID2) <> 0
  PauseThread(threadID2)
EndIf

      If Config\wave
        waveInReset_(Config\wave)
        waveInStop_(Config\wave)
        For i = 0 To Config\nBuf - 1
          If inHdr(i)
            waveInUnprepareHeader_(Config\wave,inHdr(i),SizeOf(WAVEHDR))
          EndIf
        Next
        waveInClose_(Config\wave)
      EndIf

  KillTimer_(Config\hWindow,0)
 
EndProcedure
    ;
Procedure CAPTURE_Read(hWaveIn.l,lpWaveHdr.l)
*hWave.WAVEHDR = lpWaveHdr
Config\buffer = *hWave\lpData
Config\size = *hWave\dwBytesRecorded
;dwBytesRecorded MUST BE SAVED BEFORE CALLING waveInAddBuffer -- chris319

If Config\buffer <> 0
  CopyMemory(Config\buffer, *meterBuffer, Config\size)
  CopyMemory(Config\buffer, *audioBuffer, Config\size)
EndIf

waveInAddBuffer_(hWaveIn, *hWave.WAVEHDR, SizeOf(WAVEHDR))

FILE_Append()
     
EndProcedure
    ;
    Procedure CAPTURE_GetDevices(gadId.l)
      MMNumDevice.l = waveInGetNumDevs_()
      If MMNumDevice
        For MMDeviceId=#WAVE_MAPPER To MMNumDevice-1
          MMResult.l = waveInGetDevCaps_(MMDeviceId,@Caps.WAVEINCAPS,SizeOf(WAVEINCAPS))
          If MMResult = #MMSYSERR_NOERROR
            AddGadgetItem(gadId,-1,PeekS(@Caps\szPname,#MAXPNAMELEN))
          EndIf
        Next
      EndIf
    EndProcedure
    ;
Procedure DRAW_Meter()
 If Config\buffer
 
 StartDrawing(WindowOutput(0))
 
 If Config\format\nChannels = 1
    incre = 2
    leftLimit = Config\lBuf - 2 ;2046
 Else
    incre = 4
    leftLimit = Config\lBuf - 4 ;2044
 EndIf
;
 *scope.SCOPE = Config\LScope
 max = 0
 
 i = 0
 Repeat
    value.w = PeekW(*meterBuffer + i)
     If value < 0: value = -value: EndIf
     If value > max: max = value: EndIf
     i + incre
 Until i > leftLimit ;THIS IS CORRECT

maxDefl.f = *scope\width * (max / 32767)
Box(*scope\left, *scope\top, maxDefl, *scope\height, $ffff00)
Box(maxDefl + *scope\left, *scope\top, *scope\width, *scope\height, 0)

 If Config\format\nChannels = 2
*scope.SCOPE = Config\RScope
 max = 0
;
 i = 2
 Repeat
  value.w = PeekW(*meterBuffer + i)
   If value < 0: value = -value: EndIf
   If value > max: max = value: EndIf
   i + incre
 Until i > Config\lBuf - 2 ;THIS IS CORRECT
;
maxDefl.f = *scope\width * (max / 32767)
Box(*scope\left, *scope\top, maxDefl, *scope\height, $8888ff)
Box(maxDefl + *scope\left, *scope\top, *scope\width, *scope\height, 0)
;
 EndIf
StopDrawing()
 EndIf

EndProcedure
    ;
Procedure FILE_Create()
     
      Config\recorded  = #Null ; -- MOVED HERE BY chris319
       
      If Config\File
        Config\FileId = CreateFile(#PB_Any,Config\File)
        If Config\FileId
          DisableToolBarButton(#ToolBar, #gadStart,#True)
          DisableToolBarButton(#ToolBar, #gadFile,#True)
          DisableGadget(#gadChannel,#True)
          DisableGadget(#gadFrequence,#True)
          DisableGadget(#gadDevice,#True)
          Config\Date = GetTickCount_()
          FILE_Recording(#True)
        Else
          MessageRequester("Error","Can't create file",#MB_ICONERROR)
        EndIf
      EndIf
     
    EndProcedure

Procedure FILE_Append()
      If Config\recording = #True
        Config\recorded + Config\size

;        WriteData(Config\FileId, Config\buffer, Config\size)
        WriteData(Config\FileId, *audioBuffer, Config\size)

;        StatusBarText(#StatusBar, 0,Str(Config\recorded) + " bytes",#PB_StatusBar_Center)
;        StatusBarText(#StatusBar, 1,StrF((GetTickCount_() - Config\Date)/1000,1)+" secs",#PB_StatusBar_Center)
      EndIf
EndProcedure
    ;
Procedure FILE_Recording(state.b)
     
  If state
    Config\cback   = Config\ColRecBack
    Config\cline   = Config\ColRecLine
    Config\cwave   = Config\ColRecWave
  Else
    Config\cback   = Config\ColCapBack
    Config\cline   = Config\ColCapLine
    Config\cwave   = Config\ColCapWave
  EndIf
     
Config\recording = state
    ;  Config\recorded  = #Null -- THIS LINE OF CODE MOVED TO FILE_create-- chris319

EndProcedure
    ;
    Procedure FILE_Close()

      If Config\recording
        ;Config\Date = #Null
        FILE_Recording(#False)
        CloseFile(Config\FileId)
        Delay(1000)

        FILE_raw2wav(Config\File)   

        DisableToolBarButton(#ToolBar, #gadStart,#False)
        DisableToolBarButton(#ToolBar, #gadFile,#False)
        DisableGadget(#gadChannel,#False)
        DisableGadget(#gadFrequence,#False)
        DisableGadget(#gadDevice,#False)
      EndIf

    EndProcedure
    ;
Procedure FILE_Select()
     
      File.s = SaveFileRequester("Select a file",Config\File,"snd|(*.snd)",0)
     
      If File
        Config\File = File
      EndIf
     
      StatusBarText(0,2,Config\File)
     
EndProcedure
    ;
Procedure FILE_raw2wav(File.s)
      inId.l = ReadFile(#PB_Any,File)
     
      If inId = #Null
        MessageRequester("Error", "Unable to open file",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      lBuf.l = Lof(inId)
      pBuf.l = AllocateMemory(lBuf)
      If pBuf = #Null
        MessageRequester("Error", "Unable to allocate buffer",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      ReadData(inId, pBuf,lBuf)
      CloseFile(inId)
     
      subchunk2size.l = Config\recorded
      chunksize.l = 36 + subchunk2size
     
      f$ = GetFilePart(File)
      x$ = GetPathPart(File)+Left(f$,Len(f$)-Len(GetExtensionPart(File))-1)+".wav"
     
      outId.l = CreateFile(#PB_Any,x$)
      If outId = #Null
        MessageRequester("Error", "Unable to create file",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      b.w = Config\format\wBitsPerSample
      c.w = Config\format\nChannels
      h.l = Config\format\nSamplesPerSec

      WriteString(outId, "RIFF") ; 4 bytes

    ;  WriteLong(outId, lBuf+44) ; 4 bytes
      WriteLong(outId, chunksize) ; 4 bytes -- chris319

      WriteString(outId, "WAVEfmt ") ; 8 bytes -- chris319
        ;WriteString(outId, "fmt ")
     
      ;WriteLong(outId, 16)
      WriteLong(outId, b) ; 4 bytes -- chris319
     
       
      WriteWord(outId, 1) ; 2 bytes -- PCM
      WriteWord(outId, c) ; 2 bytes
      WriteLong(outId, h) ; 4 bytes
      WriteLong(outId, c*h*(b/8)) ; 4 bytes
     
      ;WriteWord(outId, c*(h/8))
      WriteWord(outId, (c * b) / 8) ; -- blockalign 2 bytes -- chris319
       
      WriteWord(outId, b) ; 2 bytes
      WriteString(outId, "data") ; 4 bytes

      WriteLong(outId, lBuf) ; -- 4 bytes
      WriteData(outId, pBuf,lBuf)
     
      CloseFile(outId)

      FreeMemory(pBuf) ;chris319
   
      ProcedureReturn #True
     
    EndProcedure
    ;
Procedure GUI_Init()
      QuitRec = 0
      WndId.l = OpenWindow(0,100,100,800,600,"Recorder",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)
      If WndId=#Null
        MessageRequester("Error", "Unable to open window.") ;chris319 -- 6/8/12
        End
 :    EndIf

      LoadFont(0, "Arial", 24)
      TextGadget(#gadText1, 0, 150, 24, 40, "L")
      TextGadget(#gadText2, 0, 430, 24, 40, "R")
      SetGadgetFont(#gadText1, FontID(0))
      SetGadgetFont(#gadText2, FontID(0))

      Config\hWindow=WindowID(0)
      Config\output=WindowOutput(0)

      Config\hToolBar=CreateToolBar(#ToolBar,Config\hWindow)

      If Config\hToolBar=#Null : ProcedureReturn #False : EndIf
     
      If CreateStatusBar(#StatusBar,Config\hWindow)=#Null
        ProcedureReturn #False
      EndIf
     
      ToolBarStandardButton(#gadStart,#PB_ToolBarIcon_Open) ;START RECORDING
      ToolBarStandardButton(#gadStop,#PB_ToolBarIcon_Delete) ;STOP RECORDING
      ToolBarStandardButton(#gadFile,#PB_ToolBarIcon_Save) ;SAVE FILE
      ToolBarSeparator()
;      ToolBarStandardButton(#gadSndVol,#PB_ToolBarIcon_Properties) ;VOLUME CONTROL -- NOT IMPLEMENTED
      ToolBarSeparator()
     
      ToolBarToolTip(#ToolBar, #gadStart,"Record")
      ToolBarToolTip(#ToolBar, #gadStop,"Stop")
      ToolBarToolTip(#ToolBar, #gadFile,"Create a file")
;      ToolBarToolTip(#ToolBar, #gadSndVol,"Volume")
     
      GUI_TBCombo(#gadChannel,0,1,58,20) ; 04/02/2010 DrGolf
      AddGadgetItem(#gadChannel,-1,"Mono")
      AddGadgetItem(#gadChannel,-1,"Stereo")
      SetGadgetState(#gadChannel,0)

      GUI_TBCombo(#gadFrequence,2,1,80,20) ; 04/02/2010 DrGolf
      AddGadgetItem(#gadFrequence,-1,"8.0 kHz")
      AddGadgetItem(#gadFrequence,-1,"11.025 kHz")
      AddGadgetItem(#gadFrequence,-1,"12.0 kHz")
      AddGadgetItem(#gadFrequence,-1,"16.0 kHz")
      AddGadgetItem(#gadFrequence,-1,"22.05 kHz")
      AddGadgetItem(#gadFrequence,-1,"24.0 kHz")
      AddGadgetItem(#gadFrequence,-1,"32.0 kHz")
      AddGadgetItem(#gadFrequence,-1,"44.1 kHz")
      AddGadgetItem(#gadFrequence,-1,"48.0 kHz")
      SetGadgetState(#gadFrequence, 7) ;chris319 6/7/12
     
      GUI_TBCombo(#gadDevice,2,1,160,20) ; 04/02/2010 DrGolf
      CAPTURE_GetDevices(#gadDevice)
      SetGadgetState(#gadDevice,0)
     
      Frame3DGadget(#gadFrame1,0,0,0,0,"",#PB_Frame_Double)
      Frame3DGadget(#gadFrame2,0,0,0,0,"",#PB_Frame_Double)
     
      AddStatusBarField( 100)
      AddStatusBarField(  80)
      AddStatusBarField(1000)
      StatusBarText(0,0,"0 "+"bytes",#PB_StatusBar_Center)
      StatusBarText(0,1,"0.0 "+"secs",#PB_StatusBar_Center)
     
      SetWindowCallback(@GUI_CallBack())
 
     FILE_Recording(#False)
      ;GUI_Resize()

      ProcedureReturn #True

EndProcedure
    ;
Procedure GUI_Resize()
     
      WndW.l = ( WindowWidth(0)  -  4 )
      WndH.l = ( WindowHeight(0) - 60 ) >> 1

      Config\LScope\left     = 28
      Config\LScope\top      = 30
      Config\LScope\width    = WndW
      Config\LScope\height   = WndH
      Config\LScope\quarterY = Config\LScope\height >> 2
      Config\LScope\middleY  = Config\LScope\top + Config\LScope\height >> 1
      ResizeGadget(#gadFrame1,Config\LScope\left-2,Config\LScope\top-2,Config\LScope\width+4,Config\LScope\height+4)
     
      Config\RScope\left     = 28
      Config\RScope\top      = Config\LScope\top + Config\LScope\height + 6
      Config\RScope\width    = WndW
      Config\RScope\height   = WndH
      Config\RScope\quarterY = Config\RScope\height >> 2
      Config\RScope\middleY  = Config\RScope\top + Config\RScope\height >> 1
      ResizeGadget(#gadFrame2,Config\RScope\left-2,Config\RScope\top-2,Config\RScope\width+4,Config\RScope\height+4)
     
EndProcedure
    ;
Procedure GUI_TBCombo(Id,x,y,w,h)
      pos=SendMessage_(Config\hToolBar,#TB_BUTTONCOUNT,0,0)
      ToolBarSeparator()       
      SendMessage_(Config\hToolBar,#TB_GETBUTTON,pos,@separator.TBBUTTON)
      separator\iBitmap=x+w
      SendMessage_(Config\hToolBar,#TB_DELETEBUTTON,pos,0)
      SendMessage_(Config\hToolBar,#TB_INSERTBUTTON,pos,separator)
      SendMessage_(Config\hToolBar,#TB_GETITEMRECT,pos,@rc.RECT)   
      UseGadgetList(Config\hToolBar)
      ComboBoxGadget(Id,x+rc\left,y,w,h)
      UseGadgetList(Config\hWindow)
EndProcedure
    ;
Procedure AudioLoop(null)
Repeat
  WaitSemaphore(audioSemaphore)
  CAPTURE_Read(wpa, lpa)
ForEver
EndProcedure

Procedure MeterLoop(null)
Repeat
  WaitSemaphore(meterSemaphore)
  DRAW_Meter()
ForEver
EndProcedure

Procedure GUI_CallBack(hWnd.l,Msg.l,wParam.l,lParam.l)
      Result.l = #PB_ProcessPureBasicEvents
     
      Select Msg
        Case #WM_KEYDOWN
          If GetAsyncKeyState_(#VK_ESCAPE)
            QuitRec = 1
          EndIf

        Case #WM_SIZE: GUI_Resize()

        Case #WM_TIMER: SignalSemaphore(meterSemaphore) ;DRAW_Meter()

        Case #MM_WIM_DATA: wpa = wParam: lpa = lParam: SignalSemaphore(audioSemaphore)

        Case #WM_COMMAND
          Select wParam & $FFFF
            Case #gadStart      : FILE_Create()
            Case #gadStop       : FILE_Close()
            Case #gadFile       : FILE_Select()
            Case #gadFrequence  : CAPTURE_Start() ;chris319 6/7/12
            Case #gadChannel    :CAPTURE_Start() ;chris319 6/7/12
            Case #gadDevice     : CAPTURE_Start() ;chris319 6/7/12
          EndSelect

        Case #WM_GETMINMAXINFO
          *mmi.MINMAXINFO=lParam
          *mmi\ptMinTrackSize\x=#MinWidth
          *mmi\ptMinTrackSize\y=#MinHeight
      EndSelect
     
  ProcedureReturn Result
EndProcedure

;- REC MAIN

If GUI_Init()

CONFIG_Load()

CAPTURE_Start()

*meterBuffer = AllocateMemory(32768)
*audioBuffer = AllocateMemory(32768)
audioSemaphore = CreateSemaphore(0)
meterSemaphore = CreateSemaphore(0)
threadID1 = CreateThread(@AudioLoop(), #Null) ;THREAD TO MONITOR CALLBACK FLAG
threadID2 = CreateThread(@MeterLoop(), #Null) ;THREAD TO MONITOR METER FLAG

Repeat: Until WaitWindowEvent() = #WM_CLOSE Or QuitRec

CAPTURE_Stop()
If IsThread(threadID1): KillThread(threadID1): EndIf
If IsThread(threadid2): KillThread(threadID2): EndIf
If IsWindow(0) <> 0: CloseWindow(0): EndIf
If *meterBuffer <> 0: FreeMemory(*meterBuffer): EndIf
If *audioBuffer <> 0: FreeMemory(*audioBuffer): EndIf
CONFIG_Save()
End
Else
  MessageRequester("Error", "Unable to initialize GUI.") ;chris319 6/7/12
  End
EndIf









; 
; Epb 

Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: How to record audio from line-in microphone?

Post by Simo_na »

i have added the *** up the line of actualization code (modern day recording style) :D
but i don't have checked if this updates act
someone check the code , please ?? :cry:

Code: Select all

;/ Object     MME Audio Recorder 1.0 (a)
;/
;/ Date       August 2004
;/ Author     Philippe Carpentier
;/ Contact    flype@altern.org
;/ Info       MS Windows only - MME, winmm.lib - mmsystem.h

;  Bug fixes by chris319 on September 2, 2007
;  04/02/2010 : DrGolf for PB 4.50
;  01/20/2011 : Vitor_Boss® -- Fixed clamping
;  06/10/2012 : Multi-threaded version by chris319 on PB 4.61

;- REC CONSTANTES
    ;
#MinWidth      = 640
#MinHeight     = 480

#MONO = 1
#STEREO = 2

;- REC INITIALISATION

Enumeration 0 ; #CHANNEL
  #CHANNEL_LEFT
  #CHANNEL_RIGHT
EndEnumeration

Enumeration 0 ; #GADGET
  #gadFrame1
  #gadFrame2
  #gadStart
  #gadStop
  #gadSndVol
  #gadFile
  #gadChannel
  #gadFrequence
 *** #gadBit
  #gadDevice
  #gadText1
  #gadText2
EndEnumeration

Enumeration 0 ; #WINDOW
  #Window
EndEnumeration

Enumeration 0 ; #TOOLBAR
  #ToolBar
EndEnumeration

Enumeration 0 ; #STATUS BAR
  #StatusBar
EndEnumeration

;Structure WAVEFORMATEX -- NOT NEEDED IN PB 4.10 -- chris319
;  wFormatTag.w
;  nChannels.w
;  nSamplesPerSec.l
;  nAvgBytesPerSec.l
;  nBlockAlign.w
;  wBitsPerSample.w
;  cbSize.w
;EndStructure

Structure SCOPE
  channel.b
  left.l
  top.l
  width.l
  height.l
  middleY.l
  quarterY.l
EndStructure

Structure CONFIG
     
      hWindow.l           ; Window handle
      hToolBar.l          ; ToolBar handle
      hfont.l             ; Font handle
     
      Date.l              ; Start date
      size.l              ; Wave buffer size
      buffer.l            ; Wave buffer pointer
      output.l            ; WindowOutput()
      wave.l              ; Address of waveform-audio input device
      recorded.l          ; Number of bytes recorded
      recording.b         ; Record is running...
     
      File.s              ; Recording FileName (c:\unnamed.snd) ;chris319 6/7/12
      FileId.l            ; Recording FileId (#PB_Any)
      SndVol.s            ; Microsoft Volume Control (sndvol32.exe)

      format.WAVEFORMATEX ; Capturing WaveFormatEx
      lBuf.l              ; Capturing Buffer size
      nBuf.l              ; Capturing Buffer number
      nDev.l              ; Capturing Device identifier
     
      LScope.SCOPE        ; Wave form display
      RScope.SCOPE        ; Wave form display
      ScopeTimer.l        ; Scope Timer (redraw every n times)
      cback.l             ; Back color
      cline.l             ; Line color
      cwave.l             ; Wave color
      ColRecWave.l        ; Scope Record Wave Color
      ColRecBack.l        ; Scope Record Back Color
      ColRecLine.l        ; Scope Record Line Color
      ColCapWave.l        ; Scope Capture Wave Color
      ColCapBack.l        ; Scope Capture Back Color
      ColCapLine.l        ; Scope Capture Line Color
     
    EndStructure

;- GLOBAL
Global Config.CONFIG, threadID1, threadID2
;*hWave.WAVEHDR
Global Dim inHdr.WAVEHDR(16), QuitRec.l, audioSemaphore, meterSemaphore, wpa, lpa, *meterBuffer, *audioBuffer
   ;
    Config\hfont             = LoadFont(0,"Arial",7)
    Config\format\cbSize     = 0
    Config\format\wFormatTag = #WAVE_FORMAT_PCM
    Config\LScope\channel    = #CHANNEL_LEFT
    Config\RScope\channel    = #CHANNEL_RIGHT
    ;
;- REC DECLARATIONS
    ;
Declare CONFIG_Load()
Declare CONFIG_Save()

Declare CAPTURE_Stop()
Declare CAPTURE_Start()
Declare CAPTURE_Error(err.l)
Declare CAPTURE_GetDevices(gadId.l)
Declare CAPTURE_Read(hWaveIn.l,lpWaveHdr.l)

Declare FILE_Close()
Declare FILE_Append()
Declare FILE_Create()
Declare FILE_Select()
Declare FILE_Recording(state.b)
Declare FILE_raw2wav(File.s)

Declare GUI_Init()
Declare GUI_Resize()
Declare GUI_TBCombo(Id,x,y,w,h)
Declare GUI_CallBack(hWnd.l,Msg.l,wParam.l,lParam.l)

;- REC PROCEDURES
    ;
    Procedure CONFIG_Load()
     
      OpenPreferences("Recorder.ini")
     
      PreferenceGroup("Files")
      Config\File   = ReadPreferenceString("FileName","c:\unnamed.snd")
      Config\SndVol = ReadPreferenceString("SndVol","sndvol32")
     
      PreferenceGroup("Capture")
      Config\nDev     = ReadPreferenceLong("Device",0)
      Config\format\nChannels = ReadPreferenceLong("Channel", 2)
      Config\format\nSamplesPerSec   = ReadPreferenceLong("Frequency",44100)
      Config\format\wBitsPerSample = 16
      Config\nBuf = 8 ;ReadPreferenceLong("BufferNum",8) ;chris319 6/7/12
      Config\lBuf = 8192 ;ReadPreferenceLong("BufferLen", 2048) ;chris319

      PreferenceGroup("Scope")
      Config\ScopeTimer   = 20
      Config\ColRecLine   = ReadPreferenceLong("ColRecLine",  $000035)
      Config\ColRecWave   = ReadPreferenceLong("ColRecWave",  $1010E0)
      Config\ColRecBack   = ReadPreferenceLong("ColRecBack",  $000050)
      Config\ColCapLine   = ReadPreferenceLong("ColCapLine",  $004000)
      Config\ColCapWave   = ReadPreferenceLong("ColCapWave",  $20E020)
      Config\ColCapBack   = ReadPreferenceLong("ColCapBack",  $004900)
     
      PreferenceGroup("Window")
      pos.WINDOWPLACEMENT
      pos\length=SizeOf(WINDOWPLACEMENT)
      pos\ptMinPosition\x         = ReadPreferenceLong("MinPosX",0)
      pos\ptMinPosition\y         = ReadPreferenceLong("MinPoxY",0)
      pos\ptMaxPosition\x         = ReadPreferenceLong("MaxPosX",-1)
      pos\ptMaxPosition\y         = ReadPreferenceLong("MaxPosY",-1)
      pos\rcNormalPosition\left   = ReadPreferenceLong("PosX1",100)
      pos\rcNormalPosition\top    = ReadPreferenceLong("PosY1",100)
      pos\rcNormalPosition\right  = ReadPreferenceLong("PosX2",#MinWidth)
      pos\rcNormalPosition\bottom = ReadPreferenceLong("PosY2",#MinHeight)
     
      ClosePreferences()
     
      Config\cback   = Config\ColCapBack
      Config\cline   = Config\ColCapLine
      Config\cwave   = Config\ColCapWave
     
      StatusBarText(0,2,Config\File)
      SetGadgetState(#gadDevice,Config\nDev)
      SetGadgetState(#gadChannel,Config\format\nChannels - 1)

;      SetGadgetState(#gadFrequence,Config\format\nSamplesPerSec)
Select Config\format\nSamplesPerSec ;chris319 6/7/12
  *** Case 44100: SetGadgetState(#gadFrequence, 0)
  *** Case 48000: SetGadgetState(#gadFrequence, 1)
  *** Case 88200: SetGadgetState(#gadFrequence, 2)
  *** Case 96000: SetGadgetState(#gadFrequence, 3)
  *** Case 176400: SetGadgetState(#gadFrequence, 4)
  *** Case 192000: SetGadgetState(#gadFrequence, 5)

EndSelect


          
          
;SetWindowPlacement_(Config\hWindow,@pos)
;ShowWindow_(Config\hWindow,#True)
     
    EndProcedure
    ;
    Procedure CONFIG_Save()
     
pos.WINDOWPLACEMENT
pos\length = SizeOf(WINDOWPLACEMENT)
GetWindowPlacement_(Config\hWindow,@pos)
     
If CreatePreferences("Recorder.ini")
 
  PreferenceGroup("Files")
  WritePreferenceString("FileName",Config\File)
  WritePreferenceString("SndVol",Config\SndVol)
 
  PreferenceGroup("Capture")
  WritePreferenceLong("Device",Config\nDev)
  WritePreferenceLong("Channel",Config\format\nChannels)
  WritePreferenceLong("Frequency",Config\format\nSamplesPerSec)
 
  PreferenceGroup("Scope")
  WritePreferenceLong("ColRecLine",Config\ColRecLine)
  WritePreferenceLong("ColRecWave",Config\ColRecWave)
  WritePreferenceLong("ColRecBack",Config\ColRecBack)
  WritePreferenceLong("ColCapLine",Config\ColCapLine)
  WritePreferenceLong("ColCapWave",Config\ColCapWave)
  WritePreferenceLong("ColCapBack",Config\ColCapBack)
 
  PreferenceGroup("Window")
  WritePreferenceLong("MinPosX",pos\ptMinPosition\x)
  WritePreferenceLong("MinPoxY",pos\ptMinPosition\y)
  WritePreferenceLong("MaxPosX",pos\ptMaxPosition\x)
  WritePreferenceLong("MaxPosY",pos\ptMaxPosition\y)
  WritePreferenceLong("PosX1",pos\rcNormalPosition\left)
  WritePreferenceLong("PosY1",pos\rcNormalPosition\top)
  WritePreferenceLong("PosX2",pos\rcNormalPosition\right)
  WritePreferenceLong("PosY2",pos\rcNormalPosition\bottom)
 
  ClosePreferences()
  ProcedureReturn #True
 
EndIf
     
    EndProcedure
    ;
    Procedure CAPTURE_Error(err.l)

      If err
        text.s=Space(#MAXERRORLENGTH)
        waveInGetErrorText_(err,text,#MAXERRORLENGTH)
        MessageRequester("Error",text,#MB_ICONERROR)
        CAPTURE_Stop()
        End
      EndIf

    EndProcedure
    ;
Procedure CAPTURE_Start()
     
      CAPTURE_Stop()

;GET USER SETTINGS     
      Config\nDev = GetGadgetState(#gadDevice)
     
;      Config\format\nChannels = ;chris319 6/7/12
      state = GetGadgetState(#gadChannel)
      Select state
        Case 0 : Config\format\nChannels = #MONO
        Case 1 : Config\format\nChannels = #STEREO
      EndSelect
      gui_Resize() ;chris319 6/7/12

;      Config\format\nSamplesPerSec ;chris319 6/7/12
      state = GetGadgetState(#gadFrequence)
      Select state
   ***     Case 0 : Config\format\nSamplesPerSec = 44100
   ***     Case 1 : Config\format\nSamplesPerSec = 48000
   ***     Case 2 : Config\format\nSamplesPerSec = 88200
   ***     Case 3 : Config\format\nSamplesPerSec = 96000
   ***     Case 4 : Config\format\nSamplesPerSec = 176400
   ***     Case 5 : Config\format\nSamplesPerSec = 192000
      EndSelect

  Config\format\nBlockAlign = (Config\format\nChannels * Config\format\wBitsPerSample) / 8
  Config\format\nAvgBytesPerSec = Config\format\nSamplesPerSec * Config\format\nBlockAlign
  Config\format\cbSize = 0
   
      If #MMSYSERR_NOERROR = waveInOpen_(@Config\wave,#WAVE_MAPPER+Config\nDev,@Config\format,Config\hWindow,#Null,#CALLBACK_WINDOW|#WAVE_FORMAT_DIRECT)
        For i = 0 To 7
          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)

        If #MMSYSERR_NOERROR = waveInStart_(Config\wave)
          SetTimer_(Config\hWindow,0,Config\ScopeTimer,0)
        EndIf

      EndIf

If IsThread(threadID1) <> 0
  ResumeThread(threadID1)
EndIf
If IsThread(threadID2) <> 0
  ResumeThread(threadID2)
EndIf

EndProcedure
    ;
Procedure CAPTURE_Stop()
If IsThread(threadID1) <> 0
  PauseThread(threadID1)
EndIf
If IsThread(threadID2) <> 0
  PauseThread(threadID2)
EndIf

      If Config\wave
        waveInReset_(Config\wave)
        waveInStop_(Config\wave)
        For i = 0 To Config\nBuf - 1
          If inHdr(i)
            waveInUnprepareHeader_(Config\wave,inHdr(i),SizeOf(WAVEHDR))
          EndIf
        Next
        waveInClose_(Config\wave)
      EndIf

  KillTimer_(Config\hWindow,0)
 
EndProcedure
    ;
Procedure CAPTURE_Read(hWaveIn.l,lpWaveHdr.l)
*hWave.WAVEHDR = lpWaveHdr
Config\buffer = *hWave\lpData
Config\size = *hWave\dwBytesRecorded
;dwBytesRecorded MUST BE SAVED BEFORE CALLING waveInAddBuffer -- chris319

If Config\buffer <> 0
  CopyMemory(Config\buffer, *meterBuffer, Config\size)
  CopyMemory(Config\buffer, *audioBuffer, Config\size)
EndIf

waveInAddBuffer_(hWaveIn, *hWave.WAVEHDR, SizeOf(WAVEHDR))

FILE_Append()
     
EndProcedure
    ;
    Procedure CAPTURE_GetDevices(gadId.l)
      MMNumDevice.l = waveInGetNumDevs_()
      If MMNumDevice
        For MMDeviceId=#WAVE_MAPPER To MMNumDevice-1
          MMResult.l = waveInGetDevCaps_(MMDeviceId,@Caps.WAVEINCAPS,SizeOf(WAVEINCAPS))
          If MMResult = #MMSYSERR_NOERROR
            AddGadgetItem(gadId,-1,PeekS(@Caps\szPname,#MAXPNAMELEN))
          EndIf
        Next
      EndIf
    EndProcedure
    ;
Procedure DRAW_Meter()
 If Config\buffer
 
 StartDrawing(WindowOutput(0))
 
 If Config\format\nChannels = 1
    incre = 2
    leftLimit = Config\lBuf - 2 ;2046
 Else
    incre = 4
    leftLimit = Config\lBuf - 4 ;2044
 EndIf
;
 *scope.SCOPE = Config\LScope
 max = 0
 
 i = 0
 Repeat
    value.w = PeekW(*meterBuffer + i)
     If value < 0: value = -value: EndIf
     If value > max: max = value: EndIf
     i + incre
 Until i > leftLimit ;THIS IS CORRECT

maxDefl.f = *scope\width * (max / 32767)
Box(*scope\left, *scope\top, maxDefl, *scope\height, $ffff00)
Box(maxDefl + *scope\left, *scope\top, *scope\width, *scope\height, 0)

 If Config\format\nChannels = 2
*scope.SCOPE = Config\RScope
 max = 0
;
 i = 2
 Repeat
  value.w = PeekW(*meterBuffer + i)
   If value < 0: value = -value: EndIf
   If value > max: max = value: EndIf
   i + incre
 Until i > Config\lBuf - 2 ;THIS IS CORRECT
;
maxDefl.f = *scope\width * (max / 32767)
Box(*scope\left, *scope\top, maxDefl, *scope\height, $8888ff)
Box(maxDefl + *scope\left, *scope\top, *scope\width, *scope\height, 0)
;
 EndIf
StopDrawing()
 EndIf

EndProcedure
    ;
Procedure FILE_Create()
     
      Config\recorded  = #Null ; -- MOVED HERE BY chris319
       
      If Config\File
        Config\FileId = CreateFile(#PB_Any,Config\File)
        If Config\FileId
          DisableToolBarButton(#ToolBar, #gadStart,#True)
          DisableToolBarButton(#ToolBar, #gadFile,#True)
          DisableGadget(#gadChannel,#True)
          DisableGadget(#gadFrequence,#True)
          DisableGadget(#gadDevice,#True)
          Config\Date = GetTickCount_()
          FILE_Recording(#True)
        Else
          MessageRequester("Error","Can't create file",#MB_ICONERROR)
        EndIf
      EndIf
     
    EndProcedure

Procedure FILE_Append()
      If Config\recording = #True
        Config\recorded + Config\size

;        WriteData(Config\FileId, Config\buffer, Config\size)
        WriteData(Config\FileId, *audioBuffer, Config\size)

;        StatusBarText(#StatusBar, 0,Str(Config\recorded) + " bytes",#PB_StatusBar_Center)
;        StatusBarText(#StatusBar, 1,StrF((GetTickCount_() - Config\Date)/1000,1)+" secs",#PB_StatusBar_Center)
      EndIf
EndProcedure
    ;
Procedure FILE_Recording(state.b)
     
  If state
    Config\cback   = Config\ColRecBack
    Config\cline   = Config\ColRecLine
    Config\cwave   = Config\ColRecWave
  Else
    Config\cback   = Config\ColCapBack
    Config\cline   = Config\ColCapLine
    Config\cwave   = Config\ColCapWave
  EndIf
     
Config\recording = state
    ;  Config\recorded  = #Null -- THIS LINE OF CODE MOVED TO FILE_create-- chris319

EndProcedure
    ;
    Procedure FILE_Close()

      If Config\recording
        ;Config\Date = #Null
        FILE_Recording(#False)
        CloseFile(Config\FileId)
        Delay(1000)

        FILE_raw2wav(Config\File)   

        DisableToolBarButton(#ToolBar, #gadStart,#False)
        DisableToolBarButton(#ToolBar, #gadFile,#False)
        DisableGadget(#gadChannel,#False)
        DisableGadget(#gadFrequence,#False)
        DisableGadget(#gadDevice,#False)
      EndIf

    EndProcedure
    ;
Procedure FILE_Select()
     
      File.s = SaveFileRequester("Select a file",Config\File,"snd|(*.snd)",0)
     
      If File
        Config\File = File
      EndIf
     
      StatusBarText(0,2,Config\File)
     
EndProcedure
    ;
Procedure FILE_raw2wav(File.s)
      inId.l = ReadFile(#PB_Any,File)
     
      If inId = #Null
        MessageRequester("Error", "Unable to open file",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      lBuf.l = Lof(inId)
      pBuf.l = AllocateMemory(lBuf)
      If pBuf = #Null
        MessageRequester("Error", "Unable to allocate buffer",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      ReadData(inId, pBuf,lBuf)
      CloseFile(inId)
     
      subchunk2size.l = Config\recorded
      chunksize.l = 36 + subchunk2size
     
      f$ = GetFilePart(File)
      x$ = GetPathPart(File)+Left(f$,Len(f$)-Len(GetExtensionPart(File))-1)+".wav"
     
      outId.l = CreateFile(#PB_Any,x$)
      If outId = #Null
        MessageRequester("Error", "Unable to create file",#MB_ICONERROR) ; chris319
        ProcedureReturn #False
      EndIf
     
      b.w = Config\format\wBitsPerSample
      c.w = Config\format\nChannels
      h.l = Config\format\nSamplesPerSec

      WriteString(outId, "RIFF") ; 4 bytes

    ;  WriteLong(outId, lBuf+44) ; 4 bytes
      WriteLong(outId, chunksize) ; 4 bytes -- chris319

      WriteString(outId, "WAVEfmt ") ; 8 bytes -- chris319
        ;WriteString(outId, "fmt ")
     
      ;WriteLong(outId, 16)
      WriteLong(outId, b) ; 4 bytes -- chris319
     
       
      WriteWord(outId, 1) ; 2 bytes -- PCM
      WriteWord(outId, c) ; 2 bytes
      WriteLong(outId, h) ; 4 bytes
      WriteLong(outId, c*h*(b/8)) ; 4 bytes
     
      ;WriteWord(outId, c*(h/8))
      WriteWord(outId, (c * b) / 8) ; -- blockalign 2 bytes -- chris319
       
      WriteWord(outId, b) ; 2 bytes
      WriteString(outId, "data") ; 4 bytes

      WriteLong(outId, lBuf) ; -- 4 bytes
      WriteData(outId, pBuf,lBuf)
     
      CloseFile(outId)

      FreeMemory(pBuf) ;chris319
   
      ProcedureReturn #True
     
    EndProcedure
    ;
Procedure GUI_Init()
      QuitRec = 0
      WndId.l = OpenWindow(0,100,100,800,600,"Recorder",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)
      If WndId=#Null
        MessageRequester("Error", "Unable to open window.") ;chris319 -- 6/8/12
        End
 :    EndIf

      LoadFont(0, "Arial", 24)
      TextGadget(#gadText1, 0, 150, 24, 40, "L")
      TextGadget(#gadText2, 0, 430, 24, 40, "R")
      SetGadgetFont(#gadText1, FontID(0))
      SetGadgetFont(#gadText2, FontID(0))

      Config\hWindow=WindowID(0)
      Config\output=WindowOutput(0)

      Config\hToolBar=CreateToolBar(#ToolBar,Config\hWindow)

      If Config\hToolBar=#Null : ProcedureReturn #False : EndIf
     
      If CreateStatusBar(#StatusBar,Config\hWindow)=#Null
        ProcedureReturn #False
      EndIf
     
      ToolBarStandardButton(#gadStart,#PB_ToolBarIcon_Open) ;START RECORDING
      ToolBarStandardButton(#gadStop,#PB_ToolBarIcon_Delete) ;STOP RECORDING
      ToolBarStandardButton(#gadFile,#PB_ToolBarIcon_Save) ;SAVE FILE
      ToolBarSeparator()
;      ToolBarStandardButton(#gadSndVol,#PB_ToolBarIcon_Properties) ;VOLUME CONTROL -- NOT IMPLEMENTED
      ToolBarSeparator()
     
      ToolBarToolTip(#ToolBar, #gadStart,"Record")
      ToolBarToolTip(#ToolBar, #gadStop,"Stop")
      ToolBarToolTip(#ToolBar, #gadFile,"Create a file")
;      ToolBarToolTip(#ToolBar, #gadSndVol,"Volume")
     
      GUI_TBCombo(#gadChannel,0,1,58,20) ; 04/02/2010 DrGolf
      AddGadgetItem(#gadChannel,-1,"Mono")
      AddGadgetItem(#gadChannel,-1,"Stereo")
      SetGadgetState(#gadChannel,0)

      GUI_TBCombo(#gadFrequence,2,1,80,20) ; 04/02/2010 DrGolf
 ***     AddGadgetItem(#gadFrequence,-1,"44100 Hz")
 ***     AddGadgetItem(#gadFrequence,-1,"48000 Hz")
 ***     AddGadgetItem(#gadFrequence,-1,"88200 kHz")
 ***     AddGadgetItem(#gadFrequence,-1,"96000 Hz")
 ***     AddGadgetItem(#gadFrequence,-1,"176400 Hz")
 ***     AddGadgetItem(#gadFrequence,-1,"192000 kHz")
 ***     SetGadgetState(#gadFrequence, 7) ;chris319 6/7/12
      
***      GUI_TBCombo(#gadBit,2,1,80,20) 
***      AddGadgetItem(#gadbit,-1,"16 Bit")
***      AddGadgetItem(#gadbit,-1,"24 Bit")
***      SetGadgetState(#gadBit,0)
      
      GUI_TBCombo(#gadDevice,2,1,160,20) ; 04/02/2010 DrGolf
      CAPTURE_GetDevices(#gadDevice)
      SetGadgetState(#gadDevice,0)
     
      FrameGadget(#gadFrame1,0,0,0,0,"",#PB_Frame_Double)
      FrameGadget(#gadFrame2,0,0,0,0,"",#PB_Frame_Double)
     
      AddStatusBarField( 100)
      AddStatusBarField(  80)
      AddStatusBarField(1000)
      StatusBarText(0,0,"0 "+"bytes",#PB_StatusBar_Center)
      StatusBarText(0,1,"0.0 "+"secs",#PB_StatusBar_Center)
     
      SetWindowCallback(@GUI_CallBack())
 
     FILE_Recording(#False)
      ;GUI_Resize()

      ProcedureReturn #True

EndProcedure
    ;
Procedure GUI_Resize()
     
      WndW.l = ( WindowWidth(0)  -  4 )
      WndH.l = ( WindowHeight(0) - 60 ) >> 1

      Config\LScope\left     = 28
      Config\LScope\top      = 30
      Config\LScope\width    = WndW
      Config\LScope\height   = WndH
      Config\LScope\quarterY = Config\LScope\height >> 2
      Config\LScope\middleY  = Config\LScope\top + Config\LScope\height >> 1
      ResizeGadget(#gadFrame1,Config\LScope\left-2,Config\LScope\top-2,Config\LScope\width+4,Config\LScope\height+4)
     
      Config\RScope\left     = 28
      Config\RScope\top      = Config\LScope\top + Config\LScope\height + 6
      Config\RScope\width    = WndW
      Config\RScope\height   = WndH
      Config\RScope\quarterY = Config\RScope\height >> 2
      Config\RScope\middleY  = Config\RScope\top + Config\RScope\height >> 1
      ResizeGadget(#gadFrame2,Config\RScope\left-2,Config\RScope\top-2,Config\RScope\width+4,Config\RScope\height+4)
     
EndProcedure
    ;
Procedure GUI_TBCombo(Id,x,y,w,h)
      pos=SendMessage_(Config\hToolBar,#TB_BUTTONCOUNT,0,0)
      ToolBarSeparator()       
      SendMessage_(Config\hToolBar,#TB_GETBUTTON,pos,@separator.TBBUTTON)
      separator\iBitmap=x+w
      SendMessage_(Config\hToolBar,#TB_DELETEBUTTON,pos,0)
      SendMessage_(Config\hToolBar,#TB_INSERTBUTTON,pos,separator)
      SendMessage_(Config\hToolBar,#TB_GETITEMRECT,pos,@rc.RECT)   
      UseGadgetList(Config\hToolBar)
      ComboBoxGadget(Id,x+rc\left,y,w,h)
      UseGadgetList(Config\hWindow)
EndProcedure
    ;
Procedure AudioLoop(null)
Repeat
  WaitSemaphore(audioSemaphore)
  CAPTURE_Read(wpa, lpa)
ForEver
EndProcedure

Procedure MeterLoop(null)
Repeat
  WaitSemaphore(meterSemaphore)
  DRAW_Meter()
ForEver
EndProcedure

Procedure GUI_CallBack(hWnd.l,Msg.l,wParam.l,lParam.l)
      Result.l = #PB_ProcessPureBasicEvents
     
      Select Msg
        Case #WM_KEYDOWN
          If GetAsyncKeyState_(#VK_ESCAPE)
            QuitRec = 1
          EndIf

        Case #WM_SIZE: GUI_Resize()

        Case #WM_TIMER: SignalSemaphore(meterSemaphore) ;DRAW_Meter()

        Case #MM_WIM_DATA: wpa = wParam: lpa = lParam: SignalSemaphore(audioSemaphore)

        Case #WM_COMMAND
          Select wParam & $FFFF
            Case #gadStart      : FILE_Create()
            Case #gadStop       : FILE_Close()
            Case #gadFile       : FILE_Select()
            Case #gadFrequence  : CAPTURE_Start() ;chris319 6/7/12
            Case #gadChannel    :CAPTURE_Start() ;chris319 6/7/12
            Case #gadDevice     : CAPTURE_Start() ;chris319 6/7/12
          EndSelect

        Case #WM_GETMINMAXINFO
          *mmi.MINMAXINFO=lParam
          *mmi\ptMinTrackSize\x=#MinWidth
          *mmi\ptMinTrackSize\y=#MinHeight
      EndSelect
     
  ProcedureReturn Result
EndProcedure

;- REC MAIN

If GUI_Init()

CONFIG_Load()

CAPTURE_Start()

*meterBuffer = AllocateMemory(32768)
*audioBuffer = AllocateMemory(32768)
audioSemaphore = CreateSemaphore(0)
meterSemaphore = CreateSemaphore(0)
threadID1 = CreateThread(@AudioLoop(), #Null) ;THREAD TO MONITOR CALLBACK FLAG
threadID2 = CreateThread(@MeterLoop(), #Null) ;THREAD TO MONITOR METER FLAG

Repeat: Until WaitWindowEvent() = #WM_CLOSE Or QuitRec

CAPTURE_Stop()
If IsThread(threadID1): KillThread(threadID1): EndIf
If IsThread(threadid2): KillThread(threadID2): EndIf
If IsWindow(0) <> 0: CloseWindow(0): EndIf
If *meterBuffer <> 0: FreeMemory(*meterBuffer): EndIf
If *audioBuffer <> 0: FreeMemory(*audioBuffer): EndIf
CONFIG_Save()
End
Else
  MessageRequester("Error", "Unable to initialize GUI.") ;chris319 6/7/12
  End
EndIf









;
; Epb 
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: How to record audio from line-in microphone?

Post by Psychophanta »

@dobro, looks like the initial is from Flype, a code from 2002, so you have copied too...
http://www.purebasic.fr/english/viewtop ... 45#p344291

There is also this:
http://www.purebasic.fr/english/viewtop ... 27&t=54647

However, this thread is not asking for this , but for native lib functions to do this.
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: How to record audio from line-in microphone?

Post by dobro »

Psychophanta wrote:@dobro, looks like the initial is from Flype, a code from 2002, so you have copied too..

However, this thread is not asking for this , but for native lib functions to do this.

who says otherwise? // qui dit le contraire ?

regarde mieux mon post :
Dobro wrote: Flype Code :

Code:
;/ Object MME Audio Recorder 1.0 (a)
;/
;/ Date August 2004
;/ Author Philippe Carpentier
;/ Contact flype@altern.org
;/ Info MS Windows only - MME, winmm.lib - mmsystem.h


; Bug fixes by chris319 on September 2, 2007
; 04/02/2010 : DrGolf for PB 4.50
; 01/20/2011 : Vitor_Boss® -- Fixed clamping
; 06/10/2012 : Multi-threaded version by chris319 on PB 4.61

I had thought that Simo_na, was posting the same code as me
but then I saw a difference /// je pensai que Simo_na avait posté le meme code que moi , je n'avais pas vu ses ajouts ...

I never say that this code was me /// je n'ai jamais prétendu que ce code etait de moi !

However, this thread is not asking for this , but for native lib functions to do this.
yes, I was spent, next to this // oui j'etais passé a coté de ça ....

at the same time, read the microphones with native functions ..... /// en meme temps demander a lire le micro avec les fonctions native
is like asking a reading an device without a driver /// c'est comme demander a lire un périphérique, sans driver ...

not currently possible /// pas possible actuellement
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: How to record audio from line-in microphone?

Post by Simo_na »

mine directions are only a few changes to make the software more contemporary to our own times :D
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: How to record audio from line-in microphone?

Post by Psychophanta »

Ok, dobro :)
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: How to record audio from line-in microphone?

Post by dobro »

@Simo_na : Yes, and you did well!
codes, on the forum, are made for that :)

@Psychophanta : no problems :)
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
dna
User
User
Posts: 83
Joined: Wed Aug 30, 2006 12:07 am

Re: How to record audio from line-in microphone?

Post by dna »

Hello

Is there some mystery to compiling and running this?
I keep getting errors during compilation.
Post Reply