September 26, 2022, 06:44:17 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Recorder

Started by h3kt0r, May 30, 2016, 07:11:02 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

h3kt0r

May 30, 2016, 07:11:02 AM Last Edit: May 30, 2016, 07:43:33 AM by h3kt0r
Hi !

This is an example of using Windows MCI to record sound input to WAV file,
then compress the resulting WAV file to MP3 using LAME command line.
Compile as a WINDOWS target.

Attached is the project file with resources (icons) and source code.
Portions of code from J. de Jong.
Based on a Liberty Basic program written by A. Watson a while back...


( Obviously, you'll need LAME command line executable to use this :
http://www.rarewares.org/mp3-lame-bundle.php )
REM an example of using Windows MCI to record sound input to WAV file
REM Then compress the resulting WAV file to MP3 using LAME command line
REM Compile as a WINDOWS target
Autodefine "off"
$main
$include "windowssdk.inc"
$include "commctrl.inc"

Const STM_SetIcon = 368
Const SS_ICON = 0x0003
Declare MSToStr(milliseconds:Int), String
def info:SHELLEXECUTEINFO


TYPE BROWSEINFO
   DEF hOwner:UINT
   DEF pidlRoot:UINT
   DEF pszDisplayName:POINTER
   DEF lpszTitle:POINTER
   DEF ulFlags:UINT
   DEF lpfn:UINT
   DEF lParam:INT
   DEF iImage:INT
ENDTYPE

DECLARE IMPORT,SHGetPathFromIDList(pidl:INT,pszPath:STRING),INT
DECLARE IMPORT,SHBrowseForFolder(lpbi:BROWSEINFO),INT

Istring AudioDir[261]
Def hIcon,hIcon0,hIcon1 : UINT
hIcon = LoadImage("APP_ico", @IMGICON)
hIcon0 = LoadImage("WAV_ico", @IMGICON)
hIcon1 = LoadImage("LAME_ico", @IMGICON)
DEF presetMP3, presetWAV, WavName, App, Param, Mp3$ : STRING
DEF command, Time_status : STRING
DEF Xleft, Ytop, Ctl, bits, rate, RFlag, Start_time, Elapsed_time, RecorderTab, psetMP3 : INT
Istring _Log$[1000]
String FORMAT_SPECS_WAV[3]
FORMAT_SPECS_WAV[0] = "The wave format for burning audio CDs: PCM, 44.100 kHz, 16 Bits, Stereo, 172 KB/sec"
FORMAT_SPECS_WAV[1] = "The wave format for radios: PCM, 22.050 kHz, 8 Bits, Mono, 21 KB/sec"
FORMAT_SPECS_WAV[2] = "The wave format for telephones: PCM, 11.025 kHz, 8 Bits, Mono, 10 KB/sec"
String Format_specs_MP3[3]
Format_specs_MP3[0] = "preset CDs: Stereo, 192 KB/sec" + Space$(10)
Format_specs_MP3[1] = "preset Tape: Stereo, 112 KB/sec" + Space$(10)
Format_specs_MP3[2] = "preset Phone+: Mono, 24 KB/sec" + Space$(10)
Xleft = 0 :  Ytop = 0 :'Default values
Read_Ini()

DEF RecorderDlg : Dialog
CreateDialog RecorderDlg, Xleft, Ytop, 325, 200, 0x80C80080, 0, "Recorder", &RecorderDlg_handler
/*First Recorder Tab : Main*/
CONTROL RecorderDlg,@EDIT,"Log of events :",5,95,315,75,0x50A00804|@BORDER,1
CONTROL RecorderDlg,@RADIOBUTTON,"&Record",218,10,100,24,0x50010009|BS_PUSHLIKE|@GROUP,2
CONTROL RecorderDlg,@RADIOBUTTON,"&Stop",218,35,100,24,0x50010009|BS_PUSHLIKE,3
CONTROL RecorderDlg,@BUTTON,"&Convert",218,66,100,24,0x50010000,4
CONTROL RecorderDlg,@GROUPBOX,"Status",5,5,210,85,0x50000007,5
CONTROL RecorderDlg,@STATIC,"Iddle...",55,30,140,40,0x50000101,6
CONTROL RecorderDlg,@STATIC,"Timer",100,70,140,20,0x5000010B,7
CONTROL RecorderDlg,@STATIC,"ICON",10,50,32,32,SS_ICON, 8
CONTROL RecorderDlg,@RADIOBUTTON,"&Main",5,175,100,24,0x50010009|BS_PUSHLIKE|@GROUP,99
CONTROL RecorderDlg,@RADIOBUTTON,"&Options",107,175,100,24,0x50010009|BS_PUSHLIKE,100
/*Second Recorder Tab : Options*/
CONTROL RecorderDlg,@RADIOBUTTON,"&Audio CD",218,10,100,24,0x50010009|BS_PUSHLIKE|@GROUP,9
CONTROL RecorderDlg,@RADIOBUTTON,"&Radio",218,35,100,24,0x50010009|BS_PUSHLIKE,10
CONTROL RecorderDlg,@RADIOBUTTON,"&Phone",218,60,100,24,0x50010000|BS_PUSHLIKE,11
CONTROL RecorderDlg,@GROUPBOX,"WAV Output",5,5,210,80,0x50000007,12
CONTROL RecorderDlg,@STATIC,"Format Spec.",40,30,170,50,0x50000101,13
CONTROL RecorderDlg,@STATIC,"ICON",10,35,32,32,SS_ICON, 14
CONTROL RecorderDlg,@GROUPBOX,"MP3 Compression",5,87,313,40,0x50000007,15
CONTROL RecorderDlg,@STATIC,"Lame Preset",15,105,225,20,0x5000010B,16
CONTROL RecorderDlg,@BUTTON,"<",242,100,20,20,0x50010000,17
CONTROL RecorderDlg,@BUTTON,">",264,100,20,20,0x50010000,18
CONTROL RecorderDlg,@STATIC,"ICON",290,97,32,32,SS_ICON, 19
CONTROL RecorderDlg,@GROUPBOX,"Write Files in",5,129,313,40,0x50000007,20
CONTROL RecorderDlg,@EDIT,"AudioDir",10, 143 , 278, 20,0x50800080|@BORDER,21
CONTROL RecorderDlg,@BUTTON,"...",292,143,20,20,0x50010000,22


DOMODAL RecorderDlg

SUB RecorderDlg_handler()

SELECT @MESSAGE

CASE @IDCLOSEWINDOW
command = "close all"
mciSendStringA(command,NULL,0,0)
Write_Ini()
CLOSEDIALOG RecorderDlg,@IDOK

CASE @IDINITDIALOG
SendMessage(RecorderDlg, STM_SetIcon, hIcon, 0, 8)
SendMessage(RecorderDlg, STM_SetIcon, hIcon0, 0, 14)
SendMessage(RecorderDlg, STM_SetIcon, hIcon1, 0, 19)

For Ctl = 1 To 100
SETFONT RecorderDlg, "Tahoma", 8, 700, 0, Ctl
SetControlColor RecorderDlg, Ctl, Not(GetSysColor(15)), GetSysColor(15)
Next CTl

SetControlColor RecorderDlg, 1, Not(GetSysColor(24)), GetSysColor(24)
SetState(RecorderDlg, 2, 0)
SetState(RecorderDlg, 3, 1)
SetState(RecorderDlg, 100, 0)
SetState(RecorderDlg, 99, 1)
Select presetWAV
Case "AudioCD"
SetState(RecorderDlg, 9, 1) : SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[0]) : bits = 16 : rate = 44100
Case "Radio"
SetState(RecorderDlg, 10, 1) : SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[1]) : bits = 8 : rate = 22050
Case "Phone"
SetState(RecorderDlg, 11, 1) : SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[2]) : bits = 8 : rate = 11025
Default
SetState(RecorderDlg, 9, 1) : SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[0]) : presetWAV = "AudioCD" : bits = 16 : rate = 44100
EndSelect
Select presetMP3
Case "--preset cd"
psetMP3 = 0 : SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3])
Case "--preset tape"
psetMP3 = 1 : SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3])
Case "--preset phon+"
psetMP3 = 2 : SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3])
Default
psetMP3 = 0 : SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3]) : presetMP3 = "--preset cd"
EndSelect
If AudioDir="" Then AudioDir = GetStartPath
SetControlText(RecorderDlg, 21, AudioDir)
RecorderTab = 0 : Show_RcdTab(RecorderTab)


Case @IDTimer
Select @Code
Case 1
Elapsed_time = Millisecs()
Elapsed_time = (Elapsed_time - Start_time)
Time_status = MSToStr(Elapsed_time)
SetControlText (RecorderDlg, 7, Time_status)
EndSelect

CASE @IDCONTROL
SELECT @CONTROLID
CASE 2
IF @NOTIFYCODE = 0
StartTimer RecorderDlg, 1000, 1
Start_time = Millisecs()
SetControlText (RecorderDlg, 1, "Log of events :")
SETCURSOR RecorderDlg,@CSWAIT
command = "close all"
SendCom()
command = "open new type waveaudio alias capture"
SendCom()
'Set Bitrate
command = "set capture time format ms bitspersample " + Str$(bits)
SendCom()
command = "set capture channels 1 samplespersec " + Str$(rate)
SendCom()
command = "set capture alignment 1 bytespersec 8000"
SendCom()
command = "record capture": 'start the recording
SendCom()
SETCURSOR RecorderDlg,@CSARROW
SetControlText (RecorderDlg, 6, "Recording to temp file...")
RFlag = 1
EndIf

        CASE 3
IF @NOTIFYCODE = 0
if RFlag = 1

AudioDir = GetControlText(RecorderDlg, 21)
WavName = TIME$
REPLACE$ WavName, 3, 1, "h"
REPLACE$ WavName, 6, 1, "m"
WavName = AudioDir +  WavName + ".wav"
command = "stop capture"
SendCom()
command = "save capture " + WavName: 'save the recording
SendCom()
command = "close capture"
SendCom()
SetControlText (RecorderDlg, 6, "Temp file erased.\n WAV file written to disk.")
RFlag = 0
StopTimer RecorderDlg, 1
EndIf
EndIf

        CASE 4
IF @NOTIFYCODE = 0
If RFlag = 0 & WavName <> ""
'set up conversion params
'-b 96,112,128,160,192 see documentation for full bitrate range & other settings.
Mp3$ = Right$(WavName, 12) : Mp3$ = Left$(Mp3$, 8) : Mp3$ = AudioDir + Mp3$
Param = presetMP3 + Space$(1) + WavName + chr$(32) + chr$(34) + Mp3$ + ".mp3" + chr$(34)
App = GetStartPath + "lame.exe"
_Log$ = GetControlText (RecorderDlg, 1) + "\n" + "Lame " + Param
SetControlText (RecorderDlg, 1, _Log$)
/* Start the commandline application and wait until it close */
StartTimer RecorderDlg, 1000, 1
Start_time = Millisecs()
StartApp(lcase$(App),Param)
DeleteFile WavName
SetControlText (RecorderDlg, 6, "MP3 file written to disk.\n WAV file erased.")
StopTimer RecorderDlg, 1

EndIf
EndIf

        CASE 9
IF @NOTIFYCODE = 0
SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[0]) : presetWAV = "AudioCD" : bits = 16 : rate = 44100
EndIf

        CASE 10
IF @NOTIFYCODE = 0
SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[1]) : presetWAV = "Radio" :  bits = 8 : rate = 22050
EndIf

        CASE 11
IF @NOTIFYCODE = 0
SetControlText (RecorderDlg, 13, FORMAT_SPECS_WAV[2]) : presetWAV = "Phone" : bits = 8 : rate = 11025
EndIf

        CASE 17
IF @NOTIFYCODE = 0
psetMP3 = psetMP3 - 1 : If psetMP3 < 0 Then psetMP3 = 0
SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3]) : PickPresetMP3(psetMP3)
EndIf

        CASE 18
IF @NOTIFYCODE = 0
psetMP3 = psetMP3 + 1 : If psetMP3 > 2 Then psetMP3 = 2
SetControlText (RecorderDlg, 16, FORMAT_SPECS_MP3[psetMP3]) : PickPresetMP3(psetMP3)
EndIf

        CASE 22
IF @NOTIFYCODE = 0
AudioDir = GetFolder(RecorderDlg, "Select a folder to write Audio files.")
SetControlText(RecorderDlg,21,AudioDir + chr$(92))
EndIf

        CASE 99
IF @NOTIFYCODE = 0
RecorderTab = 0 : Show_RcdTab(RecorderTab)
EndIf

        CASE 100
IF @NOTIFYCODE = 0
RecorderTab = 1 : Show_RcdTab(RecorderTab)
EndIf

EndSelect

EndSelect

RETURN 0

ENDSUB

'________________________________________________________________________
Sub PickPresetMP3(psetMP3:Int)

Select psetMP3
Case 0
presetMP3 = "--preset cd"
Case 1
presetMP3 = "--preset tape"
Case 2
presetMP3 = "--preset phon+"
EndSelect

RETURN

ENDSUB
'________________________________________________________________________

Sub StartApp(App:STRING, Param:STRING)
def ret:int
def SRWexe,SRWparam:string

SRWexe = App
SRWparam = Param

info.cbSize = 15 * 4
info.fMask = SEE_MASK_NOCLOSEPROCESS
info.hwnd = 0
info.lpVerb = "Open"
info.lpFile = SRWexe
info.lpParameters = SRWparam
info.lpDirectory = ""
info.hInstApp = 0

SetControlText (RecorderDlg, 6, "Converting WAV to MP3...")
ShellExecuteExA(info)

do : ret = WaitForSingleObject(info.hprocess,0)
 'to avoid window win to freeze and not update progress bar
 wait(1)
until ret <> WAIT_TIMEOUT

return
ENDSUB

Sub SendCom()

mciSendStringA(command,NULL,0,0)
_Log$ = GetControlText (RecorderDlg, 1) + "\n" + command
SetControlText (RecorderDlg, 1, _Log$)

return
ENDSUB
'________________________________________________________________________

Sub Show_RcdTab(RecorderTab:Int)
int RecorderDlg_Ctl

For RecorderDlg_Ctl = 1 To 22
ShowWindow(RecorderDlg, @SWHIDE, RecorderDlg_Ctl)
Next RecorderDlg_Ctl

SELECT RecorderTab

case 0:'Main Tab
For RecorderDlg_Ctl = 1 To 8
ShowWindow(RecorderDlg, @SWRestore, RecorderDlg_Ctl)
Next RecorderDlg_Ctl

case 1:'Options Tab
For RecorderDlg_Ctl = 9 To 22
ShowWindow(RecorderDlg, @SWRestore, RecorderDlg_Ctl)
Next RecorderDlg_Ctl
EndSelect

return
ENDSUB
'________________________________________________________________________
Sub MSToStr(milliseconds:Int), String
Int seconds, minutes, hours

   seconds = ((milliseconds / 1000) % 60)
   minutes = ((milliseconds / 1000) / 60) % 60
   hours = (((milliseconds / 1000) / 60) / 60) % 24

   String sec, min, hrs
   if(seconds<10)
sec="0" + LTRIM$(str$(seconds))
   else            
sec= LTRIM$(str$(seconds))
endif
   if(minutes<10)
min="0" + LTRIM$(str$(minutes))
   else
min= LTRIM$(str$(minutes))
endif
   if(hours<10)
hrs="0" + LTRIM$(str$(hours))
   else
hrs= LTRIM$(str$(hours))
endif
   if(hours == 0)
return "00:" + min + ":" + sec
   else
return hrs + ":" + min + ":" + sec
endif

ENDSUB
'________________________________________________________________________
Sub Read_Ini()
'load all configuration options
Def inifile : File
Def regel, value : String

If(OpenFile(inifile, GETSTARTPATH + "Recorder.ini","R") = 0)

While (Eof(inifile) = 0)
Read inifile, value
regel = LTrim$(RTrim$(value))
value = "0"

If Instr(regel, "=")<>0
value = Right$(regel, Len(regel) - Instr(regel, "="))
value = LTrim$(value)
EndIf
If Instr(regel,"[Left]")>0 Then Xleft = Val(value)
If Instr(regel,"[Top]")>0 Then Ytop = Val(value)
If Instr(regel,"[AudioDir]")<>0 Then AudioDir = value
If Instr(regel,"[presetMP3]")<>0 Then presetMP3 = value
If Instr(regel,"[presetWAV]")<>0 Then presetWAV = value
EndWhile

CloseFile inifile
EndIf
return
ENDSUB
'________________________________________________________________________
Sub Write_Ini()

'save all configuration options
Def inifile : File
Def L,T,W,H : Int
GetSize RecorderDlg, L,T,W,H

If(OpenFile(inifile, GETSTARTPATH + "Recorder.ini","W") = 0)
Write inifile, "[Left]=" + Using("#",L)
Write inifile, "[Top]=" + Using("#",T)
Write inifile, "[AudioDir]=" + AudioDir
Write inifile, "[presetMP3]=" + presetMP3
Write inifile, "[presetWAV]=" + presetWAV
CloseFile inifile
EndIf
return
ENDSUB
'__________________________________________________
SUB GetFolder(win:WINDOW, title:STRING), STRING
'open a folderrequest dialog
DEF path[260] AS ISTRING
DEF pszPath AS INT
DEF bi:BROWSEINFO
DEF lpIDList:INT
DEF Buffer:STRING
   
   'initialize variables
   path[0] = 0
   RtlZeroMemory(bi,LEN(bi))
   bi.hOwner = win.hwnd
   bi.pszDisplayName = Buffer
   bi.lpszTitle = title
   bi.ulFlags = 0x00000001

'browse for folder
   lpIDList = SHBrowseForFolder(bi)
   IF lpIDList <> 0
       pszPath = SHGetPathFromIDList(lpIDList,path)
       CoTaskMemFree(lpIDList)
   ENDIF
   RETURN path
ENDSUB

Egil

Great example!

Thanks for sharing. ;D
Support Amateur Radio  -  Have a ham  for dinner!