QB64 Phoenix Edition
_SNDRAW - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: _SNDRAW (/showthread.php?tid=3879)



_SNDRAW - ahenry3068 - 08-22-2025

Given some Random PCM sample.    

     Assume I know Sample Rate and Bit Depth. 

I've done a little more studying of the routines. I no longer think _SNDRAW is the answer.

I'm going to use _SNDNEW _SNDMEM & _MEMPUT to do the task.

I'm still trying to work out the way these functions work and I haven't been able to find any sample code.

My current sticking point is figuring out the correct frames parameter on _SNDNEW. 4.2 has added the SAMPLERATE parameter.
So do I still calculate the frames based on _SNDRATE or can I use the data sample rate I'm using ?


RE: _SNDRAW - a740g - 08-24-2025

For short sounds, you can use _SNDNEW, _MEMSOUND, and _MEMPUT. _SNDNEW can automatically handle sample format conversion and even sample rate conversion in QB64-PE v4.2.0 and above.

A "frame" is a set of samples, one for each channel, that together describe a single point in time in the audio stream. So, for stereo audio, each frame has two samples: one for the left channel and one for the right.

For example, if your audio data is 16-bit stereo and 1024 bytes in size, then:

frames = (size / channels) / bytes_per_sample
            = (1024 / 2) / 2
            = 256 frames

Simply calculate "fames" based on the above and pass that and the other arguments based on the audio data. You do not need to perform any sample format or rate conversion. _SNDNEW does that automagically for you - just a simple data copy using _MEMSOUND and _MEMPUT will do.

Note that _SNDNEW may not be ideal for playing long streaming audio, such as from the internet or large files on disk. In those cases, I recommend using _SNDRAW or _SNDRAWBATCH.

You'll need to implement both a sample format converter and a sample rate converter. To keep things simple, start with a basic sample rate converter and perform format conversion during that step. Once you have the converted samples, you can feed them directly into _SNDRAW or _SNDRAWBATCH.

Personally, I prefer _SNDRAWBATCH since it lets me process and dispatch small chunks of audio data at a time, which helps improve performance.


RE: _SNDRAW - a740g - 08-27-2025

Here is my over-engineered streaming ZCM player with built-in format conversion and sample rate conversion. This uses _SNDRAWBATCH for playback and neatly wraps most QB64-PE _SNDRAW* functions for ease of use.

There are two libraries - zcmstream (zcmstream.bas + zcmstream.bi) and rawresampler (rawresampler.h + rawresampler.bi). rawresampler can be used standalone. However, zcmstream depends on rawresampler.

zcm_stream_test.bas is a test wrapper that shows how to use zcmstream. See ZCMStream_Play() to understand how to use rawresampler.

zcmstream API (see sources for documentation):
Code: (Select All)
FUNCTION ZCMStream_Open%% (context AS ZCMStreamType, fileName AS STRING)
SUB ZCMStream_Close (context AS ZCMStreamType)
FUNCTION ZCMStream_Is16Bit%% (context AS ZCMStreamType)
FUNCTION ZCMStream_IsStereo%% (context AS ZCMStreamType)
FUNCTION ZCMStream_GetVolume! (context AS ZCMStreamType)
SUB ZCMStream_SetVolume (context AS ZCMStreamType, volume AS SINGLE)
FUNCTION ZCMStream_GetSampleRate~& (context AS ZCMStreamType)
FUNCTION ZCMStream_GetTotalFrames~& (context AS ZCMStreamType)
FUNCTION ZCMStream_GetCurrentFrame~& (context AS ZCMStreamType)
FUNCTION ZCMStream_GetPlayingFrames~& (context AS ZCMStreamType)
FUNCTION ZCMStream_Play~& (context AS ZCMStreamType, chunkFrames AS _UNSIGNED LONG)

rawresampler API (see sources for documentation):
Code: (Select All)
FUNCTION RawResampler_S8~&& (src AS _UNSIGNED _OFFSET, dst AS _UNSIGNED _OFFSET, inSampleRate AS _UNSIGNED LONG, outSampleRate AS _UNSIGNED LONG, inputSampleFrames AS _UNSIGNED _INTEGER64, channels AS _UNSIGNED LONG)
FUNCTION RawResampler_U8~&& (src AS _UNSIGNED _OFFSET, dst AS _UNSIGNED _OFFSET, inSampleRate AS _UNSIGNED LONG, outSampleRate AS _UNSIGNED LONG, inputSampleFrames AS _UNSIGNED _INTEGER64, channels AS _UNSIGNED LONG)
FUNCTION RawResampler_S16~&& (src AS _UNSIGNED _OFFSET, dst AS _UNSIGNED _OFFSET, inSampleRate AS _UNSIGNED LONG, outSampleRate AS _UNSIGNED LONG, inputSampleFrames AS _UNSIGNED _INTEGER64, channels AS _UNSIGNED LONG)
FUNCTION RawResampler_S32~&& (src AS _UNSIGNED _OFFSET, dst AS _UNSIGNED _OFFSET, inSampleRate AS _UNSIGNED LONG, outSampleRate AS _UNSIGNED LONG, inputSampleFrames AS _UNSIGNED _INTEGER64, channels AS _UNSIGNED LONG)
FUNCTION RawResampler_F32~&& (src AS _UNSIGNED _OFFSET, dst AS _UNSIGNED _OFFSET, inSampleRate AS _UNSIGNED LONG, outSampleRate AS _UNSIGNED LONG, inputSampleFrames AS _UNSIGNED _INTEGER64, channels AS _UNSIGNED LONG)

[Image: Screenshot-2025-08-27-171801.png]

Update:

Added a third library - zcm (zcm.bas). The zcm library allows one to load and save non-streaming ZCM audio. zcm_test.bas is a test wrapper that shows how to use the zcm library.

zcm API (see sources for documentation):
Code: (Select All)
FUNCTION ZCM_Save%% (srcAudioHandle AS LONG, dstFileName AS STRING)
FUNCTION ZCM_Load& (srcFileName AS STRING)

Added some test audio files.

MIT license.

Enjoy!