MEMSOUND: Difference between revisions
Jump to navigation
Jump to search
Navigation:
Main Page with Articles and Tutorials
Keyword Reference - Alphabetical
Keyword Reference - By usage
Report a broken link
No edit summary |
(Updated all new miniaudio _MEMSOUND behavior and features. Updated example 2 that works for both OpenAL and miniaudio backends) |
||
Line 8: | Line 8: | ||
{{PageParameters}} | {{PageParameters}} | ||
* The {{Parameter|soundBlock}} [[_MEM]] type variable holds the read-only elements .OFFSET, .SIZE, .ELEMENTSIZE, and .SOUND. | * The {{Parameter|soundBlock}} [[_MEM]] type variable holds the read-only elements .OFFSET, .SIZE, .ELEMENTSIZE, .TYPE and .SOUND. | ||
** .ELEMENTSIZE will contain the number of bytes-per-sample the audio contains. | ** .OFFSET is the starting memory address of the sound sample data. | ||
** .SIZE is the size of the sample data in '''bytes''' | |||
** .ELEMENTSIZE will contain the number of '''bytes-per-sample''' the audio contains. | |||
*** Can return 1 (8-bit mono), 2 (8-bit stereo), 2 (16-bit mono), 4 (16-bit stereo), 4 (32-bit floating point mono) or 8 (32-bit floating point stereo). | |||
*** Use .TYPE to determine the data type of the sample data ([[UNSIGNED]] [[_BYTE]], [[INTEGER]] or [[SINGLE]]). | |||
** .TYPE will contain the data type of the sample data. This can be 0 ([[INTEGER]]), 1 ([[INTEGER]]), 2 ([[_UNSIGNED]] [[BYTE]]) or 4 ([[SINGLE]]) | |||
** .SOUND will contain the same handle value as returned by the [[_SNDOPEN]] function. | ** .SOUND will contain the same handle value as returned by the [[_SNDOPEN]] function. | ||
* The second parameter {{Parameter| channel%}} must be 1 (left channel/mono) or 2 (right channel, for stereo files). | * The second parameter {{Parameter| channel%}} must be 0 (interleaved/mono; version 3.1.0 and up), 1 (left channel/mono) or 2 (right channel, for stereo files). | ||
Line 48: | Line 53: | ||
''Example 2:'' Plotting a sound's waves. | ''Example 2:'' Plotting a sound's waves. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DEFLNG}} A-Z | |||
{{Cl|OPTION _EXPLICIT}} | |||
{{Cl|OPTION _EXPLICITARRAY}} | |||
{{Cl|SCREEN}} {{Cl|_NEWIMAGE}}(800, 327, 32) | {{Cl|SCREEN}} {{Cl|_NEWIMAGE}}(800, 327, 32) | ||
{{Cl|DIM}} | {{Cl|PRINT}} "Loading..."; | ||
{{Cl|DIM}} Song {{Cl|AS}} {{Cl|LONG}} | |||
Song = {{Cl|_SNDOPEN}}("OPL3 Groove.rad") ' Replace this with your (rad, mid, it, xm, s3m, mod, mp3, flac, ogg, wav) sound file | |||
{{Cl|IF}} Song < 1 {{Cl|THEN}} | |||
{{Cl|PRINT}} "Failed to load song!" | |||
{{Cl|END}} | |||
{{Cl|END}} {{Cl|IF}} | |||
{{Cl|PRINT}} "Done!" | |||
{{Cl|_SNDPLAY}} Song | |||
{{Cl|IF}} | {{Cl|DIM}} SampleData {{Cl|AS}} {{Cl|_MEM}} | ||
{{Cl|PRINT}} " | SampleData = {{Cl|_MEMSOUND}}(Song, 1) ' This can now be 0 or 1 | ||
{{Cl|IF}} SampleData.SIZE = 0 {{Cl|THEN}} | |||
{{Cl|PRINT}} "Failed to access sound sample data." | |||
{{Cl|END}} | {{Cl|END}} | ||
{{Cl|END IF}} | {{Cl|END}} {{Cl|IF}} | ||
{{Cl|DIM}} x {{Cl|AS}} {{Cl|LONG}}, i {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_INTEGER64}}, sf {{Cl|AS}} {{Cl|SINGLE}}, si {{Cl|AS}} {{Cl|INTEGER}} | |||
{{Cl|DIM}} sz {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_INTEGER64}} | |||
sz = {{Cl|_CV}}({{Cl|_UNSIGNED}} {{Cl|_INTEGER64}}, {{Cl|_MK$}}({{Cl|_OFFSET}}, SampleData.ELEMENTSIZE)) ' sz is the total size of the sound in bytes | |||
{{Cl|DO}} {{Cl|UNTIL}} {{Cl|_KEYHIT}} = 27 {{Cl|OR}} {{Cl|NOT}} {{Cl|_SNDPLAYING}}(Song) {{Cl|OR}} i + ({{Cl|_WIDTH}} * sz) > SampleData.SIZE | |||
{{Cl|CLS}} | |||
{{Cl|LOCATE}} 1, 1: {{Cl|PRINT}} i; "/"; SampleData.SIZE, "Frame Size ="; sz, "Data Type ="; SampleData.TYPE | |||
{{Cl| | {{Cl|$CHECKING}}:OFF | ||
{{Cl|IF}} (sz = 4 {{Cl|OR}} sz = 2) {{Cl|AND}} SampleData.TYPE = 1 {{Cl|THEN}} ' integer stereo or mono | |||
{{Cl| | {{Cl|FOR}} x = 0 {{Cl|TO}} {{Cl|_WIDTH}} - 1 | ||
si = {{Cl|_MEMGET}}(SampleData, SampleData.OFFSET + i + x * sz, {{Cl|INTEGER}}) 'get sound data | |||
{{Cl| | {{Cl|LINE}} (x, {{Cl|_HEIGHT}} / 2)-{{Cl|STEP}}(0, 300 * si / 32768), {{Cl|_RGB32}}(0, 111, 0) 'plot wave | ||
{{Cl|NEXT}} | |||
{{Cl|ELSEIF}} (sz = 8 {{Cl|OR}} sz = 4) {{Cl|AND}} SampleData.TYPE = 4 {{Cl|THEN}} ' floating point stereo or mono | |||
{{Cl| | {{Cl|FOR}} x = 0 {{Cl|TO}} {{Cl|_WIDTH}} - 1 | ||
x = 0 | sf = {{Cl|_MEMGET}}(SampleData, SampleData.OFFSET + i + x * sz, {{Cl|SINGLE}}) 'get sound data | ||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} / 2)-{{Cl|STEP}}(0, sf * 300), {{Cl|_RGB32}}(0, 111, 0) 'plot wave | |||
{{Cl|NEXT}} | |||
{{Cl|ELSEIF}} sz = 2 {{Cl|AND}} SampleData.TYPE = 0 {{Cl|THEN}} ' integer mono (QB64 OpenAL stuff) | |||
{{Cl|FOR}} x = 0 {{Cl|TO}} {{Cl|_WIDTH}} - 1 | |||
si = {{Cl|_MEMGET}}(SampleData, SampleData.OFFSET + i + x * sz, {{Cl|INTEGER}}) 'get sound data | |||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} / 2)-{{Cl|STEP}}(0, 300 * si / 32768), {{Cl|_RGB32}}(0, 111, 0) 'plot wave | |||
{{Cl|NEXT}} | |||
{{Cl|END}} {{Cl|IF}} | {{Cl|END}} {{Cl|IF}} | ||
{{Cl|$CHECKING}}:ON | |||
{{Cl| | |||
{{Cl|_DISPLAY}} | |||
{{Cl|_LIMIT}} 60 | |||
i = {{Cl|FIX}}({{Cl|_SNDGETPOS}}(Song) * {{Cl|_SNDRATE}}) * sz ' Calculate the new sample frame position | |||
{{Cl|LOOP}} | {{Cl|LOOP}} | ||
{{Cl|_SNDCLOSE}} | {{Cl|_SNDCLOSE}} Song 'closing the sound releases the mem blocks | ||
{{Cl|_AUTODISPLAY}} | |||
{{Cl|END}} | |||
{{CodeEnd}} | {{CodeEnd}} | ||
Revision as of 11:14, 27 August 2022
The _MEMSOUND function returns a _MEM value referring to a sound's raw data in memory using a designated sound handle created by the _SNDOPEN function.
Syntax
- soundBlock = _MEMSOUND[(soundHandle&, channel%)]
Parameters
- The soundBlock _MEM type variable holds the read-only elements .OFFSET, .SIZE, .ELEMENTSIZE, .TYPE and .SOUND.
- .OFFSET is the starting memory address of the sound sample data.
- .SIZE is the size of the sample data in bytes
- .ELEMENTSIZE will contain the number of bytes-per-sample the audio contains.
- .TYPE will contain the data type of the sample data. This can be 0 (INTEGER), 1 (INTEGER), 2 (_UNSIGNED BYTE) or 4 (SINGLE)
- .SOUND will contain the same handle value as returned by the _SNDOPEN function.
- The second parameter channel% must be 0 (interleaved/mono; version 3.1.0 and up), 1 (left channel/mono) or 2 (right channel, for stereo files).
Description
- Use the function to access raw sound data in memory for direct access.
- Sound handle values and the memory used must still be freed using _SNDCLOSE when no longer required.
- If .SIZE returns 0, that means the data could not be accessed. It may happen if you try to access the right channel in a mono file, for example.
Availability
- QB64 1.5 and up (QB64 Team)
- QBPE 0.5 and up (QB64 Phoenix Edition)
Examples
Example 1: Checking that a sound file is stereo.
song& = _SNDOPEN("song.wav") 'replace song.wav with a sound file you have IF song& = 0 THEN PRINT "Load failed.": END DIM leftchannel AS _MEM, rightchannel AS _MEM leftchannel = _MEMSOUND(song&, 1) rightchannel = _MEMSOUND(song&, 2) IF rightchannel.SIZE > 0 THEN PRINT "This file is STEREO" IF rightchannel.SIZE = 0 AND leftchannel.SIZE > 0 THEN PRINT "This file is MONO" ELSEIF rightchannel.SIZE = 0 AND leftchannel.SIZE = 0 THEN PRINT "An error occurred." END IF _SNDCLOSE song& 'closing the sound releases the mem blocks |
Example 2: Plotting a sound's waves.
DEFLNG A-Z OPTION _EXPLICIT OPTION _EXPLICITARRAY SCREEN _NEWIMAGE(800, 327, 32) PRINT "Loading..."; DIM Song AS LONG Song = _SNDOPEN("OPL3 Groove.rad") ' Replace this with your (rad, mid, it, xm, s3m, mod, mp3, flac, ogg, wav) sound file IF Song < 1 THEN PRINT "Failed to load song!" END END IF PRINT "Done!" _SNDPLAY Song DIM SampleData AS _MEM SampleData = _MEMSOUND(Song, 1) ' This can now be 0 or 1 IF SampleData.SIZE = 0 THEN PRINT "Failed to access sound sample data." END END IF DIM x AS LONG, i AS _UNSIGNED _INTEGER64, sf AS SINGLE, si AS INTEGER DIM sz AS _UNSIGNED _INTEGER64 sz = _CV(_UNSIGNED _INTEGER64, _MK$(_OFFSET, SampleData.ELEMENTSIZE)) ' sz is the total size of the sound in bytes DO UNTIL _KEYHIT = 27 OR NOT _SNDPLAYING(Song) OR i + (_WIDTH * sz) > SampleData.SIZE CLS LOCATE 1, 1: PRINT i; "/"; SampleData.SIZE, "Frame Size ="; sz, "Data Type ="; SampleData.TYPE $CHECKING:OFF IF (sz = 4 OR sz = 2) AND SampleData.TYPE = 1 THEN ' integer stereo or mono FOR x = 0 TO _WIDTH - 1 si = _MEMGET(SampleData, SampleData.OFFSET + i + x * sz, INTEGER) 'get sound data LINE (x, _HEIGHT / 2)-STEP(0, 300 * si / 32768), _RGB32(0, 111, 0) 'plot wave NEXT ELSEIF (sz = 8 OR sz = 4) AND SampleData.TYPE = 4 THEN ' floating point stereo or mono FOR x = 0 TO _WIDTH - 1 sf = _MEMGET(SampleData, SampleData.OFFSET + i + x * sz, SINGLE) 'get sound data LINE (x, _HEIGHT / 2)-STEP(0, sf * 300), _RGB32(0, 111, 0) 'plot wave NEXT ELSEIF sz = 2 AND SampleData.TYPE = 0 THEN ' integer mono (QB64 OpenAL stuff) FOR x = 0 TO _WIDTH - 1 si = _MEMGET(SampleData, SampleData.OFFSET + i + x * sz, INTEGER) 'get sound data LINE (x, _HEIGHT / 2)-STEP(0, 300 * si / 32768), _RGB32(0, 111, 0) 'plot wave NEXT END IF $CHECKING:ON _DISPLAY _LIMIT 60 i = FIX(_SNDGETPOS(Song) * _SNDRATE) * sz ' Calculate the new sample frame position LOOP _SNDCLOSE Song 'closing the sound releases the mem blocks _AUTODISPLAY END |