It's not perfect but it's improved. Changed the management of user settings (bit depth, sampling frequency and channels), hard coded buffer parameters, improved the window appearance. dropped the unimplemented volume control icon and the "LCD" display to give the CPU and graphics engine a break.
Code: Select all
;/
    ;/ Object     Audio Recorder 1.0 (a)
    ;/
    ;/ Date       August 2004
    ;/ Author     Philippe Carpentier
    ;/ Contact    flype@altern.org
    ;/ Info       MS Windows only - 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
    ;  6/8/2012 -- revised again by chris319 on PB 4.61
    ;- REC GLOBAL
    ;
Global QuitRec.l
    ;
;- REC CONSTANTES
    ;
#MinWidth      = 320
#MinHeight     = 240
#MONO = 1
#STEREO = 2
;- REC INITIALISATION
Enumeration 0 ; #CHANNEL
  #CHANNEL_LEFT
  #CHANNEL_RIGHT
EndEnumeration
Enumeration 0 ; #GADGET
  #gadFrame1
  #gadFrame2
  #gadStart
  #gadStop
  #gadSndVol
  #gadFile
  #gadChannel
  #gadResolution
  #gadFrequence
  #gadDevice
  #gadText1
  #gadText2
EndEnumeration
Enumeration 0 ; #WINDOW
  #Window
EndEnumeration
Enumeration 0 ; #TOOLBAR
  #ToolBar
EndEnumeration
Enumeration 0 ; #STATUSBAR
  #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
;      nBit.l              ; Capturing Resolution (8/16) ;chris319 6/7/12
;      nHertz.l            ; Capturing Frequency  (Hertz) ;chris319 6/7/12
;      nChannel.l          ; Capturing Channels number (Mono/Stereo) ;chris319 6/7/12
     
      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 Config.CONFIG
    Global Dim inHdr.WAVEHDR(16)
    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 Clamp(value.l,min.l,max.l)
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 DRAW_Scope()
Declare DRAW_Wave(*scope.SCOPE)
Declare DRAW_Wave8M(*scope.SCOPE)
Declare DRAW_Wave8S(*scope.SCOPE)
Declare DRAW_Wave16M(*scope.SCOPE)
Declare DRAW_Wave16S(*scope.SCOPE)
;Declare DRAW_LCD(*scope.SCOPE,lcd$) ;chris319 6/7/12
Declare DRAW_Background(*scope.SCOPE)
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 Clamp(value.l,min.l,max.l)
      If value<min : ProcedureReturn min : EndIf
      If value>max : ProcedureReturn max : EndIf 
      ProcedureReturn value
    EndProcedure
    ;
    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 = ReadPreferenceLong("Resolution",16)
      Config\nBuf = 8 ;ReadPreferenceLong("BufferNum",8) ;chris319 6/7/12
      Config\lBuf = 2048 ;ReadPreferenceLong("BufferLen", 2048) ;chris319
     
      PreferenceGroup("Scope")
      Config\ScopeTimer   = ReadPreferenceLong("ScopeTimer",25)
      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
;      SetGadgetState(#gadResolution,Config\format\wBitsPerSample)
Select Config\format\wBitsPerSample
  Case 8: SetGadgetState(#gadResolution, 0)
  Case 16: SetGadgetState(#gadResolution, 1)
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)
  WritePreferenceLong("Resolution",Config\format\wBitsPerSample)
 
  PreferenceGroup("Scope")
  WritePreferenceLong("ScopeTimer",Config\ScopeTimer)
  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\wBitsPerSample ;chris319 6/7/12
       state = GetGadgetState(#gadResolution)
       Select state
         Case 0 : Config\format\wBitsPerSample = 8
         Case 1 : Config\format\wBitsPerSample = 16
       EndSelect
    
;      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 ;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
        If #MMSYSERR_NOERROR = waveInStart_(Config\wave)
          SetTimer_(Config\hWindow,0,Config\ScopeTimer,0)
        EndIf
      EndIf
    EndProcedure
    ;
Procedure CAPTURE_Stop()
      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)
    ;  waveInAddBuffer_(hWaveIn,lpWaveHdr,SizeOf(WAVEHDR))
      *hWave.WAVEHDR=lpWaveHdr
      Config\buffer=*hWave\lpData
      Config\size=*hWave\dwBytesRecorded
    ;  dwBytesRecorded MUST BE SAVED BEFORE CALLING waveInAddBuffer -- chris319 
      waveInAddBuffer_(hWaveIn,lpWaveHdr,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_Background(*scope.SCOPE) chris319 6/7/12
;      
;       Box (*scope\left,*scope\top,*scope\width,*scope\height,Config\cback)
;       Line(*scope\left,*scope\middleY-*scope\quarterY,*scope\width,0,Config\cline)
;       Line(*scope\left,*scope\middleY+*scope\quarterY,*scope\width,0,Config\cline)
;      
;     EndProcedure
    ;
Procedure DRAW_Scope()
      If Config\buffer
        StartDrawing(WindowOutput(0)) ; 04/02/2010  DrGolf
         ;StartDrawing(Config\output)
;          DRAW_Background(Config\LScope)
;          DRAW_Background(Config\RScope)
  *scope.SCOPE = Config\LScope
  Box (*scope\left, *scope\top, *scope\width, *scope\height, Config\cback)
          DRAW_Wave(Config\LScope)
          If Config\format\nChannels = 2
  *scope.SCOPE = Config\RScope
  Box (*scope\left, *scope\top, *scope\width, *scope\height, Config\cback)
            DRAW_Wave(Config\RScope)
          EndIf
        StopDrawing()
      EndIf
    EndProcedure
;     Procedure DRAW_LCD(*scope.SCOPE,lcd$) -- GIVE THE CPU A BREAK. THERE ARE BETTER WAYS TO DO THIS      
;       DrawingMode(1)
;       FrontColor($00FFFF)
;       DrawingFont(Config\hfont)
;       Select *scope\channel
;         Case #CHANNEL_LEFT  : DrawText(*scope\left+1, *scope\top, "[L] "+lcd$)
;         Case #CHANNEL_RIGHT : DrawText(*scope\left+1, *scope\top, "[R] "+lcd$)
;       EndSelect
;       DrawingMode(0)
;       EndProcedure
    Procedure DRAW_Wave(*scope.SCOPE)
      Select Config\format\wBitsPerSample
        Case 8
          ;DRAW_LCD(*scope.SCOPE,"8 bits") ;chris319 6/7/12
          Select Config\format\nChannels
            Case #MONO : DRAW_Wave8M(*scope.SCOPE)
            Case #STEREO : DRAW_Wave8S(*scope.SCOPE)
          EndSelect
        Case 16
          ;DRAW_LCD(*scope.SCOPE,"16 bits") ;chris319 6//7/12
          Select Config\format\nChannels
            Case #MONO : DRAW_Wave16M(*scope.SCOPE)
            Case #STEREO : DRAW_Wave16S(*scope.SCOPE)
          EndSelect
      EndSelect
    EndProcedure
    ;
    Procedure DRAW_Wave8M(*scope.SCOPE)
      Protected Max_Y = (Config\RScope\height)/2
      oldx.l = *scope\left
      For i = 0 To Config\size - 1 ;chris319
        value.b=PeekB(Config\buffer+i)+$7F
        xx=Clamp(*scope\left+(i * *scope\width)/(Config\size+1),*scope\left,*scope\width)
        yy=(value**scope\height)/$FF
        If yy > Max_Y : yy = Max_Y : EndIf
        If yy < -Max_Y : yy = -Max_Y : EndIf
        LineXY(oldx,*scope\middleY+oldy,xx,*scope\middleY+yy, Config\cwave)
        oldx=xx:oldy=yy
      Next
     
    EndProcedure
    ;
    Procedure DRAW_Wave8S(*scope.SCOPE)
      Protected Max_Y = (Config\RScope\height)/2
      oldx.l=*scope\left
      For i = 0 To (Config\size - 1) Step 2 ;chris319
        value.b=PeekB(Config\buffer+i+*scope\channel*2)+$7F
        xx=Clamp(*scope\left+(i * *scope\width)/(Config\size+1),*scope\left,*scope\width)
        yy=(value**scope\height)/$FF
        If yy > Max_Y : yy = Max_Y : EndIf
        If yy < -Max_Y : yy = -Max_Y : EndIf
        LineXY(oldx,*scope\middleY+oldy,xx,*scope\middleY+yy,Config\cwave)
        oldx=xx:oldy=yy
      Next
     
    EndProcedure
    ;
Procedure DRAW_Wave16M(*scope.SCOPE) ;16 BITS MONO
Config\cwave = $00ffff
  Protected Max_Y = (Config\RScope\height)/2
      oldx.l = *scope\left
      For i = 0 To (Config\size - 2) Step 2
        value.w = PeekW(Config\buffer + i)
        xx = Clamp(*scope\left+(i**scope\width)/(Config\size+1),*scope\left,*scope\width)
        yy = (value * *scope\height)/$FFFF
        ;yy = (value * *scope\height) / $FFF
        ayy = Abs(yy)
        If ayy > vmax: vmax = ayy: EndIf
        If yy > Max_Y : yy = Max_Y : EndIf
        If yy < -Max_Y : yy = -Max_Y : EndIf
        LineXY(oldx,*scope\middleY+oldy,xx,*scope\middleY+yy,Config\cwave)
        oldx = xx: oldy = yy
      Next
  LineXY(oldx, *scope\middleY + oldy, xx, *scope\middleY + yy, Config\cwave)
oldx = xx: oldy = yy
 
EndProcedure
    ;
Procedure DRAW_Wave16S(*scope.SCOPE) ;chris319 -- 16 BITS STEREO
Config\cwave = $ddddff
      Protected Max_Y = (Config\RScope\height) / 2
    Select *scope\channel
    Case 0 ;LEFT CHANNEL
      oldx.l = *scope\left
      For i = 0 To (Config\size - 2) Step 4
        value.w = PeekW(Config\buffer + i)
        xx = Clamp(*scope\left+(i**scope\width)/(Config\size+1),*scope\left,*scope\width)
        yy = (value * *scope\height)/$FFFF
        ;yy = (value * *scope\height) / $FFF
        ayy = Abs(yy)
        If ayy > vmax: vmax = ayy: EndIf
        If yy > Max_Y : yy = Max_Y : EndIf
        If yy < -Max_Y : yy = -Max_Y : EndIf
        LineXY(oldx,*scope\middleY+oldy,xx,*scope\middleY+yy,Config\cwave)
        oldx = xx: oldy = yy
      Next
    Case 1 ;RIGHT CHANNEL
      oldx.l = *scope\left
      For i = 2 To (Config\size - 2) Step 4
        value.w = PeekW(Config\buffer + i)
        xx=Clamp(*scope\left+(i * *scope\width)/(Config\size+1),*scope\left,*scope\width)
    ;    yy = (value * *scope\height)/$FFFF
        yy = (value * *scope\height) / $FFF
        ayy = Abs(yy)
        If ayy > vmax: vmax = ayy: EndIf
        If yy > Max_Y : yy = Max_Y : EndIf
        If yy < -Max_Y : yy = -Max_Y : EndIf
        LineXY(oldx,*scope\middleY + oldy, xx, *scope\middleY + yy, Config\cwave)
        oldx = xx: oldy = yy
      Next
    EndSelect
    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(#gadResolution,#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)
        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(#gadResolution,#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,0,0,500,400,"Recorder",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_Invisible)
      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(#gadResolution,1,1,55,20) ; 04/02/2010 DrGolf
      AddGadgetItem(#gadResolution,-1,"8 bits")
      AddGadgetItem(#gadResolution,-1,"16 bits")
      SetGadgetState(#gadResolution, 1)
     
      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_Frame3D_Double)
      Frame3DGadget(#gadFrame2,0,0,0,0,"",#PB_Frame3D_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 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: DRAW_Scope()
        Case #MM_WIM_DATA: CAPTURE_Read(wParam,lParam): ;DRAW_Scope()
        Case #WM_COMMAND
          Select wParam & $FFFF
            Case #gadStart      : FILE_Create()
            Case #gadStop       : FILE_Close()
            Case #gadFile       : FILE_Select()
            ;Case #gadSndVol     : RunProgram(Config\SndVol,"","") chris319 6/7/12
            Case #gadFrequence  : CAPTURE_Start() ;chris319 6/7/12
;            Case #gadResolution : If EventType() = 6 : CAPTURE_Start() : EndIf
            Case #gadResolution : CAPTURE_Start() ;chris319 6/7/12
;            Case #gadChannel    :Debug EventType(): If EventType() = 6 : Debug "event 6" : CAPTURE_Start() : EndIf
            Case #gadChannel    :CAPTURE_Start() ;chris319 6/7/12
;            Case #gadDevice     : If EventType() = 6 : CAPTURE_Start() : EndIf
            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
;START RECORDER chris319 6/7/12
;    Procedure StartRecorder()
      If GUI_Init()
        CONFIG_Load()
        CAPTURE_Start()
        Repeat
        Until WaitWindowEvent() = #WM_CLOSE Or QuitRec
        CAPTURE_Stop()
        CONFIG_Save()
      Else
        MessageRequester("Error", "Unable to initialize GUI.") ;chris319 6/7/12
        End
      EndIf
