Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
export _memsound buffer into wav file
#1
Music 
i have devised the program shown below.  it worked well for a few midi files i created.  but i found a midi file.  where the wav file buffer is left incomplete.  from the enclosed midi file.  this program cannot export.  all 32 bars of audio.  more than half of it is left blank.

this is with using the default sound bank.  i tried with a different similar soundfont.  which was general midi.  this first happened to me on linux, debian "bookworm" base.  also happens in "bullseye" base.  downloaded qb64pe 4.2, same behavior as 4.0 which i've stayed for about a year.  changed "convertoffset()" function below.  into "clngptr()" i saw in the example for "_memsound".  no behavior change.

this was after making a few more adjustments to the program.  such as the concatenation to "wavefh".  also making sure the temporary wave file buffer.  was type "single" instead of "integer".  if the program was asked to work from a midi file.

Show Content

Code: (Select All)
'by hsiangch'ung 1-dec-2025
$SCREENHIDE
OPTION _EXPLICIT

DIM AS LONG handa, u, v, g, pp, fo
DIM handm AS _MEM, bufsiz AS _INTEGER64, wavefh AS STRING
DIM afile$, outfile$, z$
DIM rendermidi AS _BYTE

afile$ = _OPENFILEDIALOG$("Please choose an audio module.", ENVIRON$("HOME") + "/Music/", "*.mid|*.hvl|*.it|*.s3m|*.xm", "AUDIO MODULE")
IF afile$ = "" THEN SYSTEM

IF RIGHT$(afile$, 4) = ".mid" THEN
    rendermidi = 1
    wavefh = chrs$("52;49;46;46;.;.;.;.;57;41;56;45;66;6d;74;20;10;.;.;.;03;.;02;.;80;bb;.;.;.;dc;05;.;08;.;20;.;64;61;74;61")
ELSE
    rendermidi = 0
    wavefh = chrs$("52;49;46;46;.;.;.;.;57;41;56;45;66;6d;74;20;10;.;.;.;01;.;02;.;80;bb;.;.;.;ee;02;.;04;.;10;.;64;61;74;61")
END IF
wavefh = wavefh + STRING$(4, 0)

handa = _SNDOPEN(afile$)
IF handa = 0 THEN
    _MESSAGEBOX "Render Playback", "An error occurred trying to render the following file:" + CHR$(13) + afile$, "error"
    SYSTEM
END IF

outfile$ = _SAVEFILEDIALOG$("Please enter the name of the wave file to create.", ENVIRON$("HOME") + "/Music/", "*.wav", "WAVE")
IF outfile$ = "" THEN
    _SNDCLOSE handa
    _MESSAGEBOX "Render Playback", "OPERATION ABORTED", "error"
    SYSTEM
END IF

handm = _MEMSOUND(handa)
bufsiz = ConvertOffset(handm.SIZE)
u = bufsiz
v = u + &H24
pp = 0
g = 1
IF rendermidi THEN
    REDIM obuf(1 TO u) AS SINGLE
    DO UNTIL pp >= bufsiz
        obuf(g) = _MEMGET(handm, handm.OFFSET + pp, SINGLE)
        g = g + 1
        pp = pp + 4
    LOOP
ELSE
    'boy this programming system is stupid, desperately needs preprocessing
    REDIM obuf2(1 TO u) AS INTEGER
    DO UNTIL pp >= bufsiz
        obuf2(g) = _MEMGET(handm, handm.OFFSET + pp, INTEGER)
        g = g + 1
        pp = pp + 2
    LOOP
END IF
fo = FREEFILE
OPEN outfile$ FOR BINARY AS fo
PUT #fo, , wavefh
IF rendermidi THEN
    PUT #fo, , obuf()
ELSE
    PUT #fo, , obuf2()
END IF
PUT #fo, 5, v
PUT #fo, &H29, u
CLOSE fo
SHELL "sync"
IF rendermidi THEN
    ERASE obuf
ELSE
    ERASE obuf2
END IF
_MEMFREE handm

_SNDPLAY handa
_MESSAGEBOX "Render Playback", z$ + "Press 'OK' to interrupt playback." + CHR$(13) + outfile$ + CHR$(13) + "was created.", "info"
_SNDCLOSE handa
SYSTEM


FUNCTION ConvertOffset&& (value AS _OFFSET)
    DIM m AS _MEM, temp AS _INTEGER64
    m = _MEM(value)
    _MEMGET m, m.OFFSET, temp
    ConvertOffset&& = temp
    _MEMFREE m
END FUNCTION


FUNCTION chrs$ (acode$)
    DIM a$, b$, v AS INTEGER
    DIM AS LONG z1, z2
    IF acode$ = "" THEN
        chrs$ = ""
    ELSE
        a$ = ""
        z1 = 1
        z2 = INSTR(acode$, ";")
        DO
            IF z2 = 0 THEN
                b$ = MID$(acode$, z1)
            ELSE
                b$ = MID$(acode$, z1, z2 - z1)
            END IF
            IF b$ = "." THEN
                a$ = a$ + CHR$(0)
            ELSE
                v = VAL("&H" + b$)
                IF v > 0 THEN a$ = a$ + CHR$(v)
            END IF
            IF z2 > 0 THEN
                z1 = z2 + 1
                z2 = INSTR(z1, acode$, ";")
            ELSE
                EXIT DO
            END IF
        LOOP
        chrs$ = a$
    END IF
END FUNCTION

.zip   hsiangch_ong-renderplayback.zip (Size: 772.25 KB / Downloads: 13)
Reply
#2
QB64-PE handles audio loading and decoding asynchronously. This allows _SNDOPEN to return control to the caller quickly.

For long MIDI files, rendering may take some time. While you might not notice this during playback, saving the file to disk can occur before the rendering process is complete. And hence you see the silence.

To ensure _SNDOPEN waits until rendering finishes before returning, use the NoAsync flag with _SNDOPEN.
Reply
#3
this was something i totally missed.  thank you @a740g.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Play wav file in the background without a window on the forground Rudy M 12 1,125 09-18-2025, 07:08 PM
Last Post: Pete
  PEEK/POKE Video buffer BDS107 7 1,742 08-25-2022, 12:34 PM
Last Post: OldMoses

Forum Jump:


Users browsing this thread: 1 Guest(s)