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
(Add notes to highlight miniaudio changes) |
No edit summary |
||
(7 intermediate revisions by one other user not shown) | |||
Line 4: | Line 4: | ||
{{PageSyntax}} | {{PageSyntax}} | ||
: {{Parameter|soundBlock}} = [[_MEMSOUND]]({{Parameter|soundHandle&}}, {{Parameter|channel | : {{Parameter|soundBlock}} = [[_MEMSOUND]]({{Parameter|soundHandle&}}[, {{Parameter|channel&}}]) | ||
{{PageParameters}} | {{PageParameters}} | ||
* The {{Parameter|soundBlock}} [[_MEM]] type variable holds the read-only elements .OFFSET, .SIZE, .ELEMENTSIZE, .TYPE and .SOUND. | * The {{Parameter|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. | ** '''.OFFSET''' is the starting memory address of the sound sample data. | ||
** .SIZE is the size of the sample data in '''bytes''' | ** '''.SIZE''' is the size of the sample data in '''bytes''' | ||
** .ELEMENTSIZE will contain the number of '''bytes-per-sample''' the audio contains. | ** '''.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 mono) or 8 (32-bit stereo). | *** Can return 1 (8-bit mono), 2 (8-bit stereo), 2 (16-bit mono), 4 (16-bit stereo), 4 (32-bit mono) or 8 (32-bit stereo). | ||
*** Use .TYPE to determine the data type of the sample data. | *** Use '''.TYPE''' to determine the data type of the sample data. | ||
** .TYPE will contain the data type of the sample data. See [[_MEM]] for details. | ** '''.TYPE''' will contain the data type of the sample data. See [[_MEM]] for details. | ||
** .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 | * The second parameter {{Parameter|channel&}} is optional and deprecated. This was used to specify the sound channel. In '''QB64-PE v3.1.0''' and above stereo data is always interleaved. You must use '''.ELEMENTSIZE''' and '''.TYPE''' to determine the type of audio data you are dealing with. | ||
Line 23: | Line 23: | ||
* Even if the memory pointer obtained by this fuction was already freed again using [[_MEMFREE]], the respective Sound handle itself must still be freed using [[_SNDCLOSE]] when no longer required. | * Even if the memory pointer obtained by this fuction was already freed again using [[_MEMFREE]], the respective Sound handle itself 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 or the format simply does not support accessing raw PCM samples. | * 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 or the format simply does not support accessing raw PCM samples. | ||
* {{Parameter|channel&}} - 1 (left channel/mono) or 2 (right channel; for stereo files) was supported on the old OpenAL backend. For the new miniaudio backend, this must be 0. | |||
* '''_MEMSOUND''' does not work for sounds loaded with [[_SNDOPEN]] when using the '''STREAM''' or '''NODECODE''' flags. | |||
{{PageAvailability}} | {{PageAvailability}} | ||
<!-- QB64 = a version or none, QBPE = a version or all, Platforms = yes or no --> | |||
<gallery widths="48px" heights="48px" mode="nolines"> | |||
File:Qb64.png|'''v1.5''' | |||
File:Qbpe.png|'''all''' | |||
File:Apix.png | |||
File:Win.png|'''yes''' | |||
File:Lnx.png|'''yes''' | |||
File:Osx.png|'''yes''' | |||
</gallery> | |||
<!-- additional availability notes go below here --> | |||
Line 33: | Line 43: | ||
;Example 1:Checking that a sound file is stereo. | ;Example 1:Checking that a sound file is stereo. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|OPTION _EXPLICIT}} | {{Cl|OPTION}} {{Cl|_EXPLICIT}} | ||
{{Cl|PRINT}} "Loading..."; | {{Cl|CONST}} FILE_FILTER = {{Text|<nowiki>"*.wav|*.aiff|*.aifc|*.flac|*.ogg|*.mp3|*.it|*.xm|*.s3m|*.mod|*.rad|*.ahx|*.hvl|*.mus|*.hmi|*.hmp|*.hmq|*.kar|*.lds|*.mds|*.mids|*.rcp|*.r36|*.g18|*.g36|*.rmi|*.mid|*.midi|*.xfm|*.xmi|*.qoa"</nowiki>|#FFB100}} | ||
{{Cl|PRINT}} {{Text|<nowiki>"Loading..."</nowiki>|#FFB100}}; | |||
{{Cl|DIM}} Song {{Cl|AS}} {{Cl|LONG}} | {{Cl|DIM}} Song {{Cl|AS}} {{Cl|LONG}} | ||
Song = {{Cl|_SNDOPEN}}(" | Song = {{Cl|_SNDOPEN}}({{Cl|_OPENFILEDIALOG$}}({{Text|<nowiki>"Open audio file"</nowiki>|#FFB100}}, , FILE_FILTER)) | ||
{{Cl|IF}} Song < 1 {{Cl|THEN}} | {{Cl|IF}} Song < {{Text|1|#F580B1}} {{Cl|THEN}} | ||
{{Cl|PRINT}} "Failed to load sound!" | {{Cl|PRINT}} {{Text|<nowiki>"Failed to load sound!"</nowiki>|#FFB100}} | ||
{{Cl|END}} | {{Cl|END}} | ||
{{Cl|END IF}} | {{Cl|END IF}} | ||
{{Cl|PRINT}} "Done!" | {{Cl|PRINT}} {{Text|<nowiki>"Done!"</nowiki>|#FFB100}} | ||
{{Cl|DIM}} | {{Cl|DIM}} channels {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_BYTE}}: channels = {{Text|SndChannels|#55FF55}}(Song) | ||
{{Cl|IF}} | {{Cl|IF}} channels {{Cl|THEN}} | ||
{{Cl|PRINT}} "This | {{Cl|PRINT}} {{Text|<nowiki>"This sound data has"</nowiki>|#FFB100}}; channels; {{Text|<nowiki>"channels."</nowiki>|#FFB100}} | ||
{{Cl|ELSE}} | {{Cl|ELSE}} | ||
{{Cl|PRINT}} "An error occurred." | {{Cl|PRINT}} {{Text|<nowiki>"An error occurred."</nowiki>|#FFB100}} | ||
{{Cl|END IF}} | {{Cl|END IF}} | ||
{{Cl|_SNDCLOSE}} Song | {{Cl|_SNDCLOSE}} Song | ||
{{Cl|END}} | {{Cl|END}} | ||
{{Text|<nowiki>' This function returns the number of sound channels for a valid sound handle</nowiki>|#919191}} | |||
{{Cl|FUNCTION}} {{Text|SndChannels~%%|#55FF55}} (handle {{Cl|AS}} {{Cl|LONG}}) | |||
{{Cl|DECLARE LIBRARY}} | |||
{{Text|<nowiki>' This is needed to convert _OFFSET to LONG / _INTEGER64</nowiki>|#919191}} | |||
{{Cm|$IF}} {{Text|32BIT|#F580B1}} {{Cm|THEN}} | |||
{{Cl|FUNCTION}} {{Text|SndChannels.CLngPtr~&|#55FF55}} {{Cl|ALIAS}} {{Text|<nowiki>"uintptr_t"</nowiki>|#FFB100}} ({{Cl|BYVAL}} o {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_OFFSET (function)|_OFFSET}}) | |||
{{Cm|$ELSE}} | |||
{{Cl|FUNCTION}} {{Text|SndChannels.CLngPtr~&&|#55FF55}} {{Cl|ALIAS}} {{Text|<nowiki>"uintptr_t"</nowiki>|#FFB100}} ({{Cl|BYVAL}} o {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_OFFSET (function)|_OFFSET}}) | |||
{{Cm|$END IF}} | |||
{{Cl|END DECLARE}} | |||
{{Cl|DIM}} soundData {{Cl|AS}} {{Cl|_MEM}}: soundData = {{Cl|_MEMSOUND}}(handle) | |||
{{Cl|IF}} soundData.SIZE {{Cl|THEN}} | |||
{{Text|<nowiki>' See https://qb64phoenix.com/qb64wiki/index.php/MEM for details</nowiki>|#919191}} | |||
{{Cl|SELECT CASE}} soundData.TYPE | |||
{{Cl|CASE}} {{Text|260|#F580B1}} {{Text|<nowiki>' 32-bit floating point</nowiki>|#919191}} | |||
{{Text|SndChannels|#55FF55}} = {{Text|SndChannels.CLngPtr|#55FF55}}(soundData.ELEMENTSIZE) \ _SIZE_OF_SINGLE | |||
{{Cl|CASE}} {{Text|132|#F580B1}} {{Text|<nowiki>' 32-bit signed integer</nowiki>|#919191}} | |||
{{Text|SndChannels|#55FF55}} = {{Text|SndChannels.CLngPtr|#55FF55}}(soundData.ELEMENTSIZE) \ _SIZE_OF_LONG | |||
{{Cl|CASE}} {{Text|130|#F580B1}} {{Text|<nowiki>' 16-bit signed integer</nowiki>|#919191}} | |||
{{Text|SndChannels|#55FF55}} = {{Text|SndChannels.CLngPtr|#55FF55}}(soundData.ELEMENTSIZE) \ _SIZE_OF_INTEGER | |||
{{Cl| | |||
{{Cl|CASE}} {{Text|1153|#F580B1}} {{Text|<nowiki>' 8-bit unsigned integer</nowiki>|#919191}} | |||
{{Text|SndChannels|#55FF55}} = {{Text|SndChannels.CLngPtr|#55FF55}}(soundData.ELEMENTSIZE) \ _SIZE_OF_BYTE | |||
{{Cl|CASE ELSE}} {{Text|<nowiki>' unknown format</nowiki>|#919191}} | |||
{{Text|SndChannels|#55FF55}} = {{Text|1|#F580B1}} | |||
{{Cl|END SELECT}} | |||
{{Cl| | |||
{{Cl|END IF}} | {{Cl|END IF}} | ||
{{Cl|IF}} soundData.SOUND = handle {{Cl|THEN}} {{Cl|_MEMFREE}} soundData | |||
{{Cl|IF}} | |||
{{Cl|END FUNCTION}} | {{Cl|END FUNCTION}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
Line 114: | Line 109: | ||
;Example 2:Plotting a sound's waves. | ;Example 2:Plotting a sound's waves. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl| | {{Cl|OPTION}} {{Cl|_EXPLICIT}} | ||
{{Cl| | |||
{{Cl|CONST}} FILE_FILTER = {{Text|<nowiki>"*.wav|*.aiff|*.aifc|*.flac|*.ogg|*.mp3|*.it|*.xm|*.s3m|*.mod|*.rad|*.ahx|*.hvl|*.mus|*.hmi|*.hmp|*.hmq|*.kar|*.lds|*.mds|*.mids|*.rcp|*.r36|*.g18|*.g36|*.rmi|*.mid|*.midi|*.xfm|*.xmi|*.qoa"</nowiki>|#FFB100}} | |||
{{Cl|DECLARE LIBRARY}} | |||
{{Text|<nowiki>' This is needed to convert _OFFSET to LONG / _INTEGER64</nowiki>|#919191}} | |||
{{Cm|$IF}} {{Text|32BIT|#F580B1}} {{Cm|THEN}} | |||
{{Cl|FUNCTION}} {{Text|CLngPtr~&|#55FF55}} {{Cl|ALIAS}} {{Text|<nowiki>"uintptr_t"</nowiki>|#FFB100}} ({{Cl|BYVAL}} o {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_OFFSET (function)|_OFFSET}}) | |||
{{Cm|$ELSE}} | |||
{{Cl|FUNCTION}} {{Text|CLngPtr~&&|#55FF55}} {{Cl|ALIAS}} {{Text|<nowiki>"uintptr_t"</nowiki>|#FFB100}} ({{Cl|BYVAL}} o {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_OFFSET (function)|_OFFSET}}) | |||
{{Cm|$END IF}} | |||
{{Cl|END DECLARE}} | |||
{{Cl|SCREEN}} {{Cl|_NEWIMAGE}}(800, 327, 32) | {{Cl|SCREEN}} {{Cl|_NEWIMAGE}}({{Text|800|#F580B1}}, {{Text|327|#F580B1}}, {{Text|32|#F580B1}}) | ||
{{Cl|PRINT}} "Loading..."; | {{Cl|PRINT}} {{Text|<nowiki>"Loading..."</nowiki>|#FFB100}}; | ||
{{Cl|DIM}} Song {{Cl|AS}} {{Cl|LONG}} | {{Cl|DIM}} Song {{Cl|AS}} {{Cl|LONG}} | ||
Song = {{Cl|_SNDOPEN}}(" | Song = {{Cl|_SNDOPEN}}({{Cl|_OPENFILEDIALOG$}}({{Text|<nowiki>"Open audio file"</nowiki>|#FFB100}}, , FILE_FILTER)) | ||
{{Cl|IF}} Song < 1 {{Cl|THEN}} | {{Cl|IF}} Song < {{Text|1|#F580B1}} {{Cl|THEN}} | ||
{{Cl|PRINT}} "Failed to load | {{Cl|PRINT}} {{Text|<nowiki>"Failed to load sound!"</nowiki>|#FFB100}} | ||
{{Cl|END}} | {{Cl|END}} | ||
{{Cl|END}} {{Cl| | {{Cl|END IF}} | ||
{{ | {{Cl|PRINT}} {{Text|<nowiki>"Done!"</nowiki>|#FFB100}} | ||
{{Cl|_SNDPLAY}} Song | {{Cl|_SNDPLAY}} Song | ||
{{Cl|DIM}} | {{Cl|DIM}} soundData {{Cl|AS}} {{Cl|_MEM}}: soundData = {{Cl|_MEMSOUND}}(Song, {{Text|0|#F580B1}}) | ||
{{Cl|IF}} | {{Cl|IF}} soundData.SIZE = {{Text|0|#F580B1}} {{Cl|THEN}} | ||
{{Cl|PRINT}} "Failed to access sound sample data." | {{Cl|PRINT}} {{Text|<nowiki>"Failed to access sound sample data."</nowiki>|#FFB100}} | ||
{{Cl|END}} | {{Cl|END}} | ||
{{Cl|END}} {{Cl| | {{Cl|END IF}} | ||
{{Cl|DIM}} sz {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_INTEGER64}}: sz = {{Text|CLngPtr|#55FF55}}(soundData.ELEMENTSIZE) | |||
{{Cl|DIM}} x {{Cl|AS}} {{Cl|LONG}}, i {{Cl|AS}} {{Cl|_UNSIGNED}} {{Cl|_INTEGER64}} | |||
{{Cl| | {{Cl|DO...LOOP|DO UNTIL}} {{Cl|_KEYHIT}} = {{Text|27|#F580B1}} {{Cl|OR (boolean)|OR}} {{Cl|NOT}} {{Cl|_SNDPLAYING}}(Song) {{Cl|OR (boolean)|OR}} i + ({{Cl|_WIDTH (function)|_WIDTH}} * sz) > soundData.SIZE | ||
{{Cl| | {{Cl|CLS}} | ||
{{Cl|LOCATE}} {{Text|1|#F580B1}}, {{Text|1|#F580B1}}: {{Cl|PRINT}} i; {{Text|<nowiki>"/"</nowiki>|#FFB100}}; soundData.SIZE, {{Text|<nowiki>"Frame Size ="</nowiki>|#FFB100}}; sz, {{Text|<nowiki>"Data Type ="</nowiki>|#FFB100}}; soundData.TYPE | |||
{{Text|<nowiki>' See https://qb64phoenix.com/qb64wiki/index.php/MEM for details</nowiki>|#919191}} | |||
{{Cl|SELECT CASE}} soundData.TYPE | |||
{{Cl|CASE}} {{Text|130|#F580B1}} {{Text|<nowiki>' integer stereo or mono</nowiki>|#919191}} | |||
{{Cl|FOR}} x = {{Text|0|#F580B1}} {{Cl|TO}} {{Cl|_WIDTH (function)|_WIDTH}} - {{Text|1|#F580B1}} | |||
{{Cl|DIM}} si {{Cl|AS}} {{Cl|INTEGER}}: si = {{Cl|_MEMGET (function)|_MEMGET}}(soundData, soundData.OFFSET + i + x * sz, {{Cl|INTEGER}}) {{Text|<nowiki>' get sound data</nowiki>|#919191}} | |||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} \ {{Text|2|#F580B1}})-{{Cl|STEP}}({{Text|0|#F580B1}}, {{Text|300!|#F580B1}} * si / {{Text|32768!|#F580B1}}), {{Cl|_RGB32}}({{Text|0|#F580B1}}, {{Text|111|#F580B1}}, {{Text|0|#F580B1}}) {{Text|<nowiki>'plot wave</nowiki>|#919191}} | |||
{{Cl|NEXT}} | |||
{{Cl| | {{Cl|CASE}} {{Text|132|#F580B1}} {{Text|<nowiki>' long stereo or mono</nowiki>|#919191}} | ||
{{Cl|FOR}} x = {{Text|0|#F580B1}} {{Cl|TO}} {{Cl|_WIDTH (function)|_WIDTH}} - {{Text|1|#F580B1}} | |||
{{Cl|DIM}} sl {{Cl|AS}} {{Cl|LONG}}: sl = {{Cl|_MEMGET (function)|_MEMGET}}(soundData, soundData.OFFSET + i + x * sz, {{Cl|LONG}}) {{Text|<nowiki>' get sound data</nowiki>|#919191}} | |||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} \ {{Text|2|#F580B1}})-{{Cl|STEP}}({{Text|0|#F580B1}}, {{Text|300!|#F580B1}} * sl / {{Text|2147483648!|#F580B1}}), {{Cl|_RGB32}}({{Text|0|#F580B1}}, {{Text|111|#F580B1}}, {{Text|0|#F580B1}}) {{Text|<nowiki>'plot wave</nowiki>|#919191}} | |||
{{Cl|NEXT}} | |||
{{Cl|CASE}} {{Text|260|#F580B1}} {{Text|<nowiki>' floating point stereo or mono</nowiki>|#919191}} | |||
{{Cl|FOR}} x = {{Text|0|#F580B1}} {{Cl|TO}} {{Cl|_WIDTH (function)|_WIDTH}} - {{Text|1|#F580B1}} | |||
{{Cl|DIM}} sf {{Cl|AS}} {{Cl|SINGLE}}: sf = {{Cl|_MEMGET (function)|_MEMGET}}(soundData, soundData.OFFSET + i + x * sz, {{Cl|SINGLE}}) {{Text|<nowiki>' get sound data</nowiki>|#919191}} | |||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} \ {{Text|2|#F580B1}})-{{Cl|STEP}}({{Text|0|#F580B1}}, sf * {{Text|300!|#F580B1}}), {{Cl|_RGB32}}({{Text|0|#F580B1}}, {{Text|111|#F580B1}}, {{Text|0|#F580B1}}) {{Text|<nowiki>'plot wave</nowiki>|#919191}} | |||
{{Cl|NEXT}} | |||
{{Cl|CASE}} {{Text|1153|#F580B1}} {{Text|<nowiki>' unsigned byte stereo or mono</nowiki>|#919191}} | |||
{{Cl|FOR}} x = {{Text|0|#F580B1}} {{Cl|TO}} {{Cl|_WIDTH (function)|_WIDTH}} - {{Text|1|#F580B1}} | |||
{{Cl|DIM}} sb {{Cl|AS}} {{Cl|_BYTE}}: sb = {{Cl|_MEMGET (function)|_MEMGET}}(soundData, soundData.OFFSET + i + x * sz, {{Cl|_UNSIGNED}} {{Cl|_BYTE}}) {{Cl|XOR}} {{Text|&H80|#F580B1}} {{Text|<nowiki>' get sound data and convert to signed</nowiki>|#919191}} | |||
{{Cl|LINE}} (x, {{Cl|_HEIGHT}} \ {{Text|2|#F580B1}})-{{Cl|STEP}}({{Text|0|#F580B1}}, {{Text|300!|#F580B1}} * sb / {{Text|128!|#F580B1}}), {{Cl|_RGB32}}({{Text|0|#F580B1}}, {{Text|111|#F580B1}}, {{Text|0|#F580B1}}) {{Text|<nowiki>' plot wave</nowiki>|#919191}} | |||
{{Cl|NEXT}} | |||
{{Cl|END SELECT}} | |||
{{Cl| | |||
{{Cl|_DISPLAY}} | {{Cl|_DISPLAY}} | ||
i = {{Cl|FIX}}({{Cl|_SNDGETPOS}}(Song) * {{Cl|_SNDRATE}}) * sz ' | {{Cl|_LIMIT}} {{Text|60|#F580B1}} | ||
i = {{Cl|FIX}}({{Cl|_SNDGETPOS}}(Song) * {{Cl|_SNDRATE}}) * sz {{Text|<nowiki>' calculate the new sample frame position</nowiki>|#919191}} | |||
{{Cl|LOOP}} | {{Cl|LOOP}} | ||
{{Cl|_SNDCLOSE}} Song | {{Cl|_SNDCLOSE}} Song | ||
{{Cl|_AUTODISPLAY}} | {{Cl|_AUTODISPLAY}} | ||
{{Cl|END}} | {{Cl|END}} |
Latest revision as of 14:57, 21 November 2024
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 or _SNDNEW 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.
- Can return 1 (8-bit mono), 2 (8-bit stereo), 2 (16-bit mono), 4 (16-bit stereo), 4 (32-bit mono) or 8 (32-bit stereo).
- Use .TYPE to determine the data type of the sample data.
- .TYPE will contain the data type of the sample data. See _MEM for details.
- .SOUND will contain the same handle value as returned by the _SNDOPEN function.
- The second parameter channel& is optional and deprecated. This was used to specify the sound channel. In QB64-PE v3.1.0 and above stereo data is always interleaved. You must use .ELEMENTSIZE and .TYPE to determine the type of audio data you are dealing with.
Description
- Use this function to obtain a pointer to the raw sound data in memory for direct access.
- Even if the memory pointer obtained by this fuction was already freed again using _MEMFREE, the respective Sound handle itself 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 or the format simply does not support accessing raw PCM samples.
- channel& - 1 (left channel/mono) or 2 (right channel; for stereo files) was supported on the old OpenAL backend. For the new miniaudio backend, this must be 0.
- _MEMSOUND does not work for sounds loaded with _SNDOPEN when using the STREAM or NODECODE flags.
Availability
Examples
- Example 1
- Checking that a sound file is stereo.
OPTION _EXPLICIT CONST FILE_FILTER = "*.wav|*.aiff|*.aifc|*.flac|*.ogg|*.mp3|*.it|*.xm|*.s3m|*.mod|*.rad|*.ahx|*.hvl|*.mus|*.hmi|*.hmp|*.hmq|*.kar|*.lds|*.mds|*.mids|*.rcp|*.r36|*.g18|*.g36|*.rmi|*.mid|*.midi|*.xfm|*.xmi|*.qoa" PRINT "Loading..."; DIM Song AS LONG Song = _SNDOPEN(_OPENFILEDIALOG$("Open audio file", , FILE_FILTER)) IF Song < 1 THEN PRINT "Failed to load sound!" END END IF PRINT "Done!" DIM channels AS _UNSIGNED _BYTE: channels = SndChannels(Song) IF channels THEN PRINT "This sound data has"; channels; "channels." ELSE PRINT "An error occurred." END IF _SNDCLOSE Song END ' This function returns the number of sound channels for a valid sound handle FUNCTION SndChannels~%% (handle AS LONG) DECLARE LIBRARY ' This is needed to convert _OFFSET to LONG / _INTEGER64 $IF 32BIT THEN FUNCTION SndChannels.CLngPtr~& ALIAS "uintptr_t" (BYVAL o AS _UNSIGNED _OFFSET) $ELSE FUNCTION SndChannels.CLngPtr~&& ALIAS "uintptr_t" (BYVAL o AS _UNSIGNED _OFFSET) $END IF END DECLARE DIM soundData AS _MEM: soundData = _MEMSOUND(handle) IF soundData.SIZE THEN ' See https://qb64phoenix.com/qb64wiki/index.php/MEM for details SELECT CASE soundData.TYPE CASE 260 ' 32-bit floating point SndChannels = SndChannels.CLngPtr(soundData.ELEMENTSIZE) \ _SIZE_OF_SINGLE CASE 132 ' 32-bit signed integer SndChannels = SndChannels.CLngPtr(soundData.ELEMENTSIZE) \ _SIZE_OF_LONG CASE 130 ' 16-bit signed integer SndChannels = SndChannels.CLngPtr(soundData.ELEMENTSIZE) \ _SIZE_OF_INTEGER CASE 1153 ' 8-bit unsigned integer SndChannels = SndChannels.CLngPtr(soundData.ELEMENTSIZE) \ _SIZE_OF_BYTE CASE ELSE ' unknown format SndChannels = 1 END SELECT END IF IF soundData.SOUND = handle THEN _MEMFREE soundData END FUNCTION |
- Example 2
- Plotting a sound's waves.
OPTION _EXPLICIT CONST FILE_FILTER = "*.wav|*.aiff|*.aifc|*.flac|*.ogg|*.mp3|*.it|*.xm|*.s3m|*.mod|*.rad|*.ahx|*.hvl|*.mus|*.hmi|*.hmp|*.hmq|*.kar|*.lds|*.mds|*.mids|*.rcp|*.r36|*.g18|*.g36|*.rmi|*.mid|*.midi|*.xfm|*.xmi|*.qoa" DECLARE LIBRARY ' This is needed to convert _OFFSET to LONG / _INTEGER64 $IF 32BIT THEN FUNCTION CLngPtr~& ALIAS "uintptr_t" (BYVAL o AS _UNSIGNED _OFFSET) $ELSE FUNCTION CLngPtr~&& ALIAS "uintptr_t" (BYVAL o AS _UNSIGNED _OFFSET) $END IF END DECLARE SCREEN _NEWIMAGE(800, 327, 32) PRINT "Loading..."; DIM Song AS LONG Song = _SNDOPEN(_OPENFILEDIALOG$("Open audio file", , FILE_FILTER)) IF Song < 1 THEN PRINT "Failed to load sound!" END END IF PRINT "Done!" _SNDPLAY Song DIM soundData AS _MEM: soundData = _MEMSOUND(Song, 0) IF soundData.SIZE = 0 THEN PRINT "Failed to access sound sample data." END END IF DIM sz AS _UNSIGNED _INTEGER64: sz = CLngPtr(soundData.ELEMENTSIZE) DIM x AS LONG, i AS _UNSIGNED _INTEGER64 DO UNTIL _KEYHIT = 27 OR NOT _SNDPLAYING(Song) OR i + (_WIDTH * sz) > soundData.SIZE CLS LOCATE 1, 1: PRINT i; "/"; soundData.SIZE, "Frame Size ="; sz, "Data Type ="; soundData.TYPE ' See https://qb64phoenix.com/qb64wiki/index.php/MEM for details SELECT CASE soundData.TYPE CASE 130 ' integer stereo or mono FOR x = 0 TO _WIDTH - 1 DIM si AS INTEGER: si = _MEMGET(soundData, soundData.OFFSET + i + x * sz, INTEGER) ' get sound data LINE (x, _HEIGHT \ 2)-STEP(0, 300! * si / 32768!), _RGB32(0, 111, 0) 'plot wave NEXT CASE 132 ' long stereo or mono FOR x = 0 TO _WIDTH - 1 DIM sl AS LONG: sl = _MEMGET(soundData, soundData.OFFSET + i + x * sz, LONG) ' get sound data LINE (x, _HEIGHT \ 2)-STEP(0, 300! * sl / 2147483648!), _RGB32(0, 111, 0) 'plot wave NEXT CASE 260 ' floating point stereo or mono FOR x = 0 TO _WIDTH - 1 DIM sf AS SINGLE: sf = _MEMGET(soundData, soundData.OFFSET + i + x * sz, SINGLE) ' get sound data LINE (x, _HEIGHT \ 2)-STEP(0, sf * 300!), _RGB32(0, 111, 0) 'plot wave NEXT CASE 1153 ' unsigned byte stereo or mono FOR x = 0 TO _WIDTH - 1 DIM sb AS _BYTE: sb = _MEMGET(soundData, soundData.OFFSET + i + x * sz, _UNSIGNED _BYTE) XOR &H80 ' get sound data and convert to signed LINE (x, _HEIGHT \ 2)-STEP(0, 300! * sb / 128!), _RGB32(0, 111, 0) ' plot wave NEXT END SELECT _DISPLAY _LIMIT 60 i = FIX(_SNDGETPOS(Song) * _SNDRATE) * sz ' calculate the new sample frame position LOOP _SNDCLOSE Song _AUTODISPLAY END |
See also