LB Booster
General >> Suggestion Box >> Recwave "talking.wav", 44100 / Stoprec
http://lbb.conforums.com/index.cgi?board=suggestions&action=display&num=1404743872

Recwave "talking.wav", 44100 / Stoprec
Post by James on Jul 7th, 2014, 2:37pm

Thanks Richard for all the hard work!

It would be neat to be able to start/stop recording audio like this:

[recbutton]
Recwave "singin.wav", 44100
wait

[stopbutton]
Stoprec
wait

I haven't been able to record audio very well in vista. embarassed

------------

Rom. 1:16) For I am not ashamed of the gospel of Christ: for it is the power of God unto salvation to every one that believeth;
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Jul 7th, 2014, 5:46pm

on Jul 7th, 2014, 2:37pm, James wrote:
It would be neat to be able to start/stop recording audio like this: Recwave "singin.wav", 44100

Using the mciSendString API is nearly as simple, isn't it? I think I'm right in saying that you only need to send three commands to start recording audio to a file:

"open new type waveaudio alias capture"
"set capture parameters"
"record capture"

Then to stop the recording:

"stop capture"
"save capture filename"
"delete capture"
"close capture"

As far as I know this technique works in 'modern' versions of Windows, but I can't say I've actually tried it.

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by Rod on Jul 8th, 2014, 6:36pm

This code shows some of the mci command strings in use. It works on LBB Win8.1


Code:
 'this records saves and loads 1.5 second long
        'audio as 8bit .wav files it runs at
        '11025 samples per second for 1.5 seconds = 16537 samples
        'in each file. samples range from 0 to 255
        true=1
        false=0
        recording=false   ' are we recording right now or not?
        mid=127
        sampos=45

        WindowWidth = 800
        WindowHeight = 600
        UpperLeftX=int((DisplayWidth-WindowWidth)/2)
        UpperLeftY=int((DisplayHeight-WindowHeight)/2)



        nomainwin
        graphicbox #main.current, 130,   5, 630, 256
        graphicbox #main.library, 130, 266, 630, 256
        button #main.record,"Record",[record], UL,   5,   7,  90,  25
        button #main.save,"Save",[save], UL,   5,  37,  90,  25
        button #main.load,"Load",[load], UL,   5,  67,  90,  25
        button #main.play,"Play",[play], UL,   5,  97,  90,  25
        button #main.left,"<",[left], UL, 5,127,40,25
        button #main.right,">",[right], UL 55,127,40,25



        open "Sound Recording" for window as #main
        print #main.current, "down; fill darkgray; flush"
        print #main.library, "down; fill darkgray; flush"
        print #main, "font ms_sans_serif 10"


[mainloop]
        wait
        goto [mainloop]

[record]
        if recording=true then wait
        r$=mciSendString$("close all")
        r$=mciSendString$("open new type waveaudio alias capture")
        gosub [setRate]
        r$=mciSendString$("record capture")
        if r$="error" then [error]
        recording=true
        t=time$("milliseconds")
        while time$("milliseconds")<t+1500
        wend
        r$=mciSendString$("stop capture")
        r$=mciSendString$("save capture capture.wav")
        r$=mciSendString$("close capture")
        recording=false
        gosub [chart]
        wait

[play]
        if recording=true then wait
        r$=mciSendString$("open capture.wav type waveaudio alias capture")
        if r$="error" then [error]
        r$=mciSendString$("play capture wait")
        r$=mciSendString$("close capture")
        wait

[save]
        if recording=true then wait
        filedialog "Save As","*.wav",wave$
        if wave$="" then wait
        if lower$(right$(wave$,4))<>".wav" then wave$=wave$+".wav"
        r$=mciSendString$("open capture.wav type waveaudio alias capture")
        if r$="error" then [error]
        r$=mciSendString$("save capture " + wave$)
        r$=mciSendString$("close capture")
        wait

[load]
        if recording=true then wait
        filedialog "Open As","*.wav",wave$
        if wave$="" then wait
        wave$=chr$(34)+wave$+chr$(34)
        r$=mciSendString$("open " +wave$+ " type waveaudio alias capture")
        if r$="error" then [error]
        r$=mciSendString$("save capture capture.wav")
        r$=mciSendString$("close capture")
        gosub [chart]
        wait




[chart]
        xpos=0
        print #main.current, "discard ;redraw ;down"
        print #main.library, "discard ;redraw ;down"
        open "capture.wav" for binary as #live
        length=lof(#live)
        seek #live, sampos
        for n=1 to 630
        samnum=asc(input$(#live, 1))
        if samnum>mid then
        print #main.current, "color red ;size 1; line ";xpos;" ";mid;" ";xpos;" ";samnum
        else
        print #main.current, "color red ;size 1; line ";xpos;" ";samnum;" ";xpos;" ";mid
        end if
        xpos=xpos+1
        next n
        close #live
        return

[right]
        sampos=sampos+630
        if sampos>length-630 then sampos=length-630
        gosub [chart]
        wait

[left]  sampos=sampos-630
        if sampos<45 then sampos=45
        gosub [chart]
        wait


[quit]
        close #main
        end


[setRate]
        r$=mciSendString$("set capture time format ms bitspersample 8")
        r$=mciSendString$("set capture channels 1 samplespersec 11025")
        r$=mciSendString$("set capture alignment 1 bytespersec 8000")
        return


Function GetShortPathName$(lPath$)
        lPath$=lPath$+chr$(0)
        sPath$=space$(256)
        lenPath=len(sPath$)
        calldll #kernel32, "GetShortPathNameA",lPath$ as ptr,_
        sPath$ as ptr,lenPath as long,r as long
        GetShortPathName$=left$(sPath$,r)
        end function



Function mciSendString$(s$)
        buffer$=space$(1024)+chr$(0)
        calldll #winmm,"mciSendStringA",s$ as ptr,buffer$ as ptr, 1028 as long, 0 as long, r as long
        buffer$=left$(buffer$, instr(buffer$, chr$(0)) - 1)
        if r>0 then
            mciSendString$="error"
        else
            mciSendString$=buffer$
        end if
        End Function




 

Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Jul 9th, 2014, 09:58am

Thanks guys!

Is this code public domain? grin
Re: Recwave "talking.wav", 44100 / Stopr
Post by Rod on Jul 16th, 2014, 6:27pm

Pretty much, though it is a vast resource. It isn't specifically LBB based it is more an API scripting syntax.

http://msdn.microsoft.com/en-gb/library/windows/desktop/dd757161(v=vs.85).aspx
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Jul 21st, 2014, 07:20am

It seems like Vista doesn't work with the 44100 quality mciSendString, but with the low quality. huh
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Jul 21st, 2014, 09:06am

on Jul 21st, 2014, 07:20am, James wrote:
It seems like Vista doesn't work with the 44100 quality mciSendString, but with the low quality.

I don't think it's the version of Windows that matters, but the capabilities of the sound hardware and drivers you have installed on your PC.

To check what audio recording formats are available go to Control Panel... Sound... Recording... [select device]... Properties... Advanced.

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Jul 21st, 2014, 2:21pm

I don't know... huh

http://social.msdn.microsoft.com/Forums/vstudio/en-US/ba35bff1-8a3a-4a55-8cc4-24eb4f225d15/audio-capture-in-vista-defaulting-to-8-bit-pcm-wrongly-needs-to-work-in-xp-and-vista?forum=windowspro-audiodevelopment
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Jul 21st, 2014, 4:05pm

on Jul 21st, 2014, 2:21pm, James wrote:
I don't know...

It's not entirely clear from that link whether they upgraded the OS without any hardware change (in which case I agree it looks like an OS issue) or whether they were running Vista on a completely different PC (in which case it could still be a hardware/driver issue).

Richard.

Re: Recwave "talking.wav", 44100 / Stopr
Post by Rod on Jul 21st, 2014, 7:21pm

Quote:
It seems like Vista doesn't work with the 44100 quality mciSendString, but with the low quality.


If you are referring to my posted code then yes it is set to low quality recording. This was to limit the data stream for analysis and display.

If you have tried to set higher quality recording and it fails then be sure you have all of the latest drivers and windows updates installed.

I would say that almost all hardware capable of running Vista is capable of recording 44k stereo audio. That's basic cd quality, most Vista+ hardware is capable of better quality.

Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Jul 22nd, 2014, 01:19am

Are you certain that you're requesting a 'standard' set of parameters? For example Rod's code specifies 11025 Hz sampling with 8 bits-per-sample (I've corrected the bytespersec value which is incorrect in Rod's original listing):

Code:
    r$=mciSendString$("set capture time format ms bitspersample 8")
    r$=mciSendString$("set capture channels 1 samplespersec 11025")
    r$=mciSendString$("set capture alignment 1 bytespersec 11025") 

If you change only the sampling rate, to 44100 Hz, it may well not work because 8 bits-per-sample is not normal at that speed:

Code:
    r$=mciSendString$("set capture time format ms bitspersample 8")
    r$=mciSendString$("set capture channels 1 samplespersec 44100")
    r$=mciSendString$("set capture alignment 1 bytespersec 44100") 

To ensure correct operation you should specify 16 bits-per-sample:

Code:
    r$=mciSendString$("set capture time format ms bitspersample 16")
    r$=mciSendString$("set capture channels 1 samplespersec 44100")
    r$=mciSendString$("set capture alignment 2 bytespersec 88200") 

You may even find that mono recording at that sample rate is not supported, and you need to change it to stereo:

Code:
    r$=mciSendString$("set capture time format ms bitspersample 16")
    r$=mciSendString$("set capture channels 2 samplespersec 44100")
    r$=mciSendString$("set capture alignment 4 bytespersec 176400") 

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Jul 22nd, 2014, 3:54pm

Thanks Richard for your help! It seems possible that a noncompliant bytespersec value caused the same code to work fine on an XP laptop but not another VISTA laptop. shocked
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Jul 22nd, 2014, 6:55pm

I can't seem to record higher than 88kbps...
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Jul 24th, 2014, 2:54pm

on Jul 22nd, 2014, 6:55pm, James wrote:
I can't seem to record higher than 88kbps...

It may be that MCI imposes a limit - either to ensure reliable recording or as part of the measures taken in Windows to prevent illegal ripping of music etc.

If you're recording from the microphone or line-input, the input filter and ADC may not be capable of delivering 44100 Hz quality anyway.

Richard.

Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 7th, 2014, 2:51pm

Chris, my friend and I were trying to record on his computer. He has a high-quality ZOOM microphone, and a high quality sound card/device, but I couldn't get any success.

It would be cool if Liberty Basic could record like it does playwave "soundfile.wav"

I need recording ability for one of my main programs, and now with XP going by the wayside, I'm trusting God to help me.
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Aug 7th, 2014, 4:51pm

on Aug 7th, 2014, 2:51pm, James wrote:
I couldn't get any success.

Did it not work at all (which would surprise me) or did it work but only at 22050 Hz sampling (which is probably to be expected)?

Whenever I've done audio recording I've used the lower-level waveIn API functions, which seem to work fine at 44100 Hz, but of course are rather more complicated to get going. I have BBC BASIC code (which in principle could be run in LBB using the 'translator bypass' feature) but I've never tried to do it in Liberty BASIC.

If you want to find out whether it would work, you can try running this BBC executable.

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 11th, 2014, 4:11pm

Wow, Mr. Russel, this seems to work fine! Sorry for the delay, I was finally able to test it on something besides XP. That would be great if we could use this ability in Liberty Basic!
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Aug 14th, 2014, 1:33pm

on Aug 11th, 2014, 4:11pm, James wrote:
That would be great if we could use this ability in Liberty Basic!

One of the problems is that the BBC BASIC code uses an array-of-structures, and sadly Liberty BASIC doesn't support arrays of structures. sad

If I get a chance I will look into the possibility of using a kludge to resolve this issue.

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 15th, 2014, 06:24am

Thanks very much! grin
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Aug 15th, 2014, 12:04pm

Try this. It records 44100 Hz stereo to a WAV file; I've tested it with LBB 2.64 on Windows XP, 7 and 8.1. There is no source selection or setting of level, you will need to do that in Control Panel (Sound... Recording...). If you develop this into something amazing, I would appreciate an acknowledgement of my contribution. Enjoy!

Code:
    ' Audio recorder (c) Richard Russell, 15-Aug-2014
    nomainwin
    global record.flag, record.buff, wavfile$

    filedialog "Save WAV file", "*.wav", wavfile$
    if wavfile$ = "" then end

    button #w.start, "Start Recording", startrec, UL, 100, 100
    button #w.stop, "Stop Recording", stoprec, UL, 100, 200
    open "Audio recorder" for window as #w
    #w "trapclose quit"
    #w.stop "!disable"
    call record.init
    timer 50, record.poll
    wait

sub quit handle$
    timer 0
    call record.exit
    close #w
    end
end sub

sub startrec handle$
    #w.start "!disable"
    #w.stop "!enable"
    call record.start wavfile$
end sub

sub stoprec handle$
    call record.stop
    #w.stop "!disable"
    #w.start "!enable"
end sub

sub record.init
    ' Initialise the wave input format:
    struct waveFormatEx, _
        wFormatTag as word, nChannels as word, nSamplesPerSec as ulong, _
        nAvgBytesPerSec as ulong, nBlockAlign as word, _
        wBitsPerSample as word, cbSize as word

    waveFormatEx.wFormatTag.struct = _WAVE_FORMAT_PCM
    waveFormatEx.nChannels.struct = 2 
    waveFormatEx.nSamplesPerSec.struct = 44100
    waveFormatEx.wBitsPerSample.struct = 16
    waveFormatEx.nBlockAlign.struct = waveFormatEx.nChannels.struct * waveFormatEx.wBitsPerSample.struct / 8
    waveFormatEx.nAvgBytesPerSec.struct = waveFormatEx.nSamplesPerSec.struct * waveFormatEx.nBlockAlign.struct

    ' Create wave headers:
    struct WAVEHDR, lpData as ulong, dwBufferLength as ulong, _
        dwBytesRecorded as ulong, dwUser as ulong, dwFlags as ulong, _
        dwLoops as ulong, lpNext as ulong, Reserved as ulong

    ' Fill in wave headers, allocate, prepare and add buffers:
    BytesPerBuffer = 16384

    struct WaveIn, hndl as ulong
    calldll #winmm, "waveInOpen", WaveIn as struct, _WAVE_MAPPER as long, _
        waveFormatEx as struct, 0 as long, 0 as long, _
        0 as long, ret as long
    if ret then notice "waveInOpen failed" : end

    for buff = 0 TO 7
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)

        ' Kludge to fake array of structures:
        calldll #kernel32, "GlobalAlloc", _GMEM_FIXED as long, _
            l as ulong, header as ulong
        calldll #kernel32, "GlobalAlloc", _GMEM_FIXED as long, _
            BytesPerBuffer as ulong, buffer as ulong
        Headers(buff) = header
        WAVEHDR.lpData.struct = buffer
        WAVEHDR.dwBufferLength.struct = BytesPerBuffer
        WAVEHDR.dwFlags.struct = 0
        calldll #kernel32, "RtlMoveMemory", header as ulong, _
            WAVEHDR as struct, l as ulong, ret as long

        calldll #winmm, "waveInPrepareHeader", h as ulong, _
            header as ulong, l as ulong, ret as long
        if ret then notice "waveInPrepareHeader failed" : end
  
        calldll #winmm, "waveInAddBuffer", h as ulong, _
            header as ulong, l as ulong, ret as long
        if ret then notice "waveInAddBuffer failed" : end
      next

      record.buff = 0
      calldll #winmm, "waveInStart", h as ulong, ret as long
      if ret then notice, "waveInStart failed" : end
end sub

sub record.start filename$ 
    open filename$ for output as #recordfile
    format$ = waveFormatEx.struct
    print #recordfile, "RIFF";
    print #recordfile, d4$(0); ' Filled in later
    print #recordfile, "WAVE";
    print #recordfile, "fmt ";
    print #recordfile, d4$(16);
    print #recordfile, left$(format$,16);
    print #recordfile, "data";
    print #recordfile, d4$(0); ' Filled in later
    seek #recordfile, 44
    record.flag = 1
end sub

sub record.stop
    record.flag = 0
    size = lof(#recordfile)
    seek #recordfile, 4
    print #recordfile, d4$(size - 8);
    seek #recordfile, 40
    print #recordfile, d4$(size - 44);    
    seek #recordfile, size
    close #recordfile
end sub

sub record.exit
    h = WaveIn.hndl.struct
    calldll #winmm, "waveInStop", h as ulong, r as long
    calldll #winmm, "waveInReset", h as ulong, r as long
    for i = 0 to 7
        header = Headers(i)
        WAVEHDR.struct = header
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)
        p = WAVEHDR.lpData.struct
        calldll #winmm, "waveInUnprepareHeader", h as ulong, _
            header as ulong, l as ulong, r as long
        calldll #kernel32, "GlobalFree", p as ulong, r as long
        calldll #kernel32, "GlobalFree", header as ulong, r as long
    next i
    calldll #winmm, "waveInClose", h as ulong, r as long
end sub

sub record.poll
    header = Headers(record.buff)
    WAVEHDR.struct = header
    if WAVEHDR.dwFlags.struct and _WHDR_DONE then
        WAVEHDR.dwFlags.struct = WAVEHDR.dwFlags.struct and (-_WHDR_DONE-1)
        if record.flag then
            h = hwnd(#recordfile)
            d = WAVEHDR.lpData.struct
            l = WAVEHDR.dwBytesRecorded.struct
            struct written, n as ulong
            calldll #kernel32, "WriteFile", h as ulong, d as ulong, _
                l as ulong, written as struct, 0 as ulong, r as long
        end if
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)
        calldll #winmm, "waveInAddBuffer", h as ulong, header as ulong, _
            l as ulong, r as long
    record.buff = (record.buff + 1) mod 8
    end if
end sub

function d4$(n)
    a = n mod 256
    n = int(n/256)
    b = n mod 256
    n = int(n/256)
    c = n mod 256
    n = int(n/256)
    d = n mod 256
    d4$ = chr$(a)+chr$(b)+chr$(c)+chr$(d)
end function 

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 24th, 2014, 3:21pm

Thank you very much!
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 24th, 2014, 3:50pm

Mr. Russell, can I post this code in the LB forum? Can people use it in their LB 4.04 programs? smiley
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Aug 24th, 2014, 4:28pm

on Aug 24th, 2014, 3:50pm, James wrote:
can I post this code in the LB forum? Can people use it in their LB 4.04 programs? smiley

As it stands it's not fully compatible with LB 4.04. There are a few changes that would need to be made:
  1. It uses some Windows Constants that LB 4.04 doesn't know about. You would need to replace them with numbers or global variables.

  2. It uses TIMER with a SUB. Although the LB docs describe this usage, there's a bug in LB 4.04 which means you have to use a branch label instead.

  3. It uses the HWND() function with a file, rather than with a window. This is an LBB extension to the language so doesn't work in LB 4.04.
If you can fix those incompatibilities then of course it's OK to post it so long as it retains the copyright notice.

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 25th, 2014, 5:59pm

Code:
   ' Audio recorder (c) Richard Russell, 15-Aug-2014
    nomainwin
    global record.flag, record.buff, wavfile$

    filedialog "Save WAV file", "*.wav", wavfile$
    if wavfile$ = "" then end

    button #w.start, "Start Recording", startrec, UL, 100, 100
    button #w.stop, "Stop Recording", stoprec, UL, 100, 200
    open "Audio recorder" for window as #w
    #w "trapclose [quit]"
    #w.stop "!disable"
    call record.init
    timer 50, [recordpoll]
    wait

[quit]
    timer 0
    call record.exit
    close #w
    end


sub startrec handle$
    #w.start "!disable"
    #w.stop "!enable"
    call record.start wavfile$
end sub

sub stoprec handle$
    call record.stop
    #w.stop "!disable"
    #w.start "!enable"
end sub

sub record.init
    ' Initialise the wave input format:
    struct waveFormatEx, _
        wFormatTag as word, nChannels as word, nSamplesPerSec as ulong, _
        nAvgBytesPerSec as ulong, nBlockAlign as word, _
        wBitsPerSample as word, cbSize as word

    WAVEFORMATPCM = hexdec("0x0001") '_WAVE_FORMAT_PCM

    waveFormatEx.wFormatTag.struct = WAVEFORMATPCM
    waveFormatEx.nChannels.struct = 2
    waveFormatEx.nSamplesPerSec.struct = 44100
    waveFormatEx.wBitsPerSample.struct = 16
    waveFormatEx.nBlockAlign.struct = waveFormatEx.nChannels.struct * waveFormatEx.wBitsPerSample.struct / 8
    waveFormatEx.nAvgBytesPerSec.struct = waveFormatEx.nSamplesPerSec.struct * waveFormatEx.nBlockAlign.struct

    ' Create wave headers:
    struct WAVEHDR, lpData as ulong, dwBufferLength as ulong, _
        dwBytesRecorded as ulong, dwUser as ulong, dwFlags as ulong, _
        dwLoops as ulong, lpNext as ulong, Reserved as ulong

    ' Fill in wave headers, allocate, prepare and add buffers:
    BytesPerBuffer = 16384

    WAVEMAPPER = hexdec("0xFFFFFFFF") '_WAVE_MAPPER

    struct WaveIn, hndl as ulong
    calldll #winmm, "waveInOpen", WaveIn as struct, WAVEMAPPER as long, _
        waveFormatEx as struct, 0 as long, 0 as long, _
        0 as long, ret as long
    if ret then notice "waveInOpen failed" : end

    for buff = 0 TO 7
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)

        ' Kludge to fake array of structures:
        calldll #kernel32, "GlobalAlloc", _GMEM_FIXED as long, _
            l as ulong, header as ulong
        calldll #kernel32, "GlobalAlloc", _GMEM_FIXED as long, _
            BytesPerBuffer as ulong, buffer as ulong
        Headers(buff) = header
        WAVEHDR.lpData.struct = buffer
        WAVEHDR.dwBufferLength.struct = BytesPerBuffer
        WAVEHDR.dwFlags.struct = 0
        calldll #kernel32, "RtlMoveMemory", header as ulong, _
            WAVEHDR as struct, l as ulong, ret as long

        calldll #winmm, "waveInPrepareHeader", h as ulong, _
            header as ulong, l as ulong, ret as long
        if ret then notice "waveInPrepareHeader failed" : end

        calldll #winmm, "waveInAddBuffer", h as ulong, _
            header as ulong, l as ulong, ret as long
        if ret then notice "waveInAddBuffer failed" : end
      next

      record.buff = 0
      calldll #winmm, "waveInStart", h as ulong, ret as long
      if ret then notice, "waveInStart failed" : end
end sub

sub record.start filename$ 
    open filename$ for output as #recordfile
    format$ = waveFormatEx.struct
    print #recordfile, "RIFF";
    print #recordfile, d4$(0); ' Filled in later
    print #recordfile, "WAVE";
    print #recordfile, "fmt ";
    print #recordfile, d4$(16);
    print #recordfile, left$(format$,16);
    print #recordfile, "data";
    print #recordfile, d4$(0); ' Filled in later
    seek #recordfile, 44
    record.flag = 1
end sub

sub record.stop
    record.flag = 0
    size = lof(#recordfile)
    seek #recordfile, 4
    print #recordfile, d4$(size - 8);
    seek #recordfile, 40
    print #recordfile, d4$(size - 44);
    seek #recordfile, size
    close #recordfile
end sub

sub record.exit
    h = WaveIn.hndl.struct
    calldll #winmm, "waveInStop", h as ulong, r as long
    calldll #winmm, "waveInReset", h as ulong, r as long
    for i = 0 to 7
        header = Headers(i)
        WAVEHDR.struct = header
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)
        p = WAVEHDR.lpData.struct
        calldll #winmm, "waveInUnprepareHeader", h as ulong, _
            header as ulong, l as ulong, r as long
        calldll #kernel32, "GlobalFree", p as ulong, r as long
        calldll #kernel32, "GlobalFree", header as ulong, r as long
    next i
    calldll #winmm, "waveInClose", h as ulong, r as long
end sub

[recordpoll]
    WHDRDONE = 1 '_WHDR_DONE
    header = Headers(record.buff)
    WAVEHDR.struct = header
    if WAVEHDR.dwFlags.struct and WHDRDONE then
        WAVEHDR.dwFlags.struct = WAVEHDR.dwFlags.struct and (WHDRDONE-1)
        if record.flag then
            h = hwnd(#recordfile)
            d = WAVEHDR.lpData.struct
            l = WAVEHDR.dwBytesRecorded.struct
            struct written, n as ulong
            calldll #kernel32, "WriteFile", h as ulong, d as ulong, _
                l as ulong, written as struct, 0 as ulong, r as long
        end if
        h = WaveIn.hndl.struct
        l = len(WAVEHDR.struct)
        calldll #winmm, "waveInAddBuffer", h as ulong, header as ulong, _
            l as ulong, r as long
    record.buff = (record.buff + 1) mod 8
    end if
wait

function d4$(n)
    a = n mod 256
    n = int(n/256)
    b = n mod 256
    n = int(n/256)
    c = n mod 256
    n = int(n/256)
    d = n mod 256
    d4$ = chr$(a)+chr$(b)+chr$(c)+chr$(d)
end function
 


This is as far as I've got...
Re: Recwave "talking.wav", 44100 / Stopr
Post by Richard Russell on Aug 26th, 2014, 10:13am

on Aug 25th, 2014, 5:59pm, James wrote:
This is as far as I've got...

Yes, the hwnd(#recordfile) is the tricky thing to workaround in order to make it LB 4.04 compatible (that's assuming it would run fast enough in LB). One possible solution might be to use the fact that LB's structures are effectively strings, so you can do things like:

Code:
    test$ = test.struct 

(it doesn't look as though it should work, but it does).

Using that technique it might be possible to eliminate the WriteFile API call and thus lose the HWND() too.

But I'm not motivated to work it out in detail, because I want people to use LBB; making my programs compatible with LB 4.04 is hardly in my best interests! I'd rather you posted my original code to the LB forum with a note saying that it only runs in LBB, but we all know what would happen if you did....

Richard.
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 26th, 2014, 5:26pm

Well, you have helped us with LBB and I now want to appreciate you taking the time to write this code. Thank you very much for your work! smiley
Re: Recwave "talking.wav", 44100 / Stopr
Post by James on Aug 1st, 2017, 09:31am

Hi, Mr. Russel,

If someone wants to use/modify your wave recording code, they just have to say in their code:

Base wave code courtesy of Richard Russel, copyright owned by him

Right?

-Thanks
James