Yeah, I know I can physically count the elements in the def statements and use that with a #def, but if I neglect to do so, or forget to update the #def that reflects the def'd array element count, then I have a potential issue.
I've been cogitating on how to implement something like this programmatically as a function, but am coming up empty handed for a robust solution. Had considered using addressof for the var name and the next dim'd var, doing the math to try to figure that out, but that is a house of cards that can come down pretty quickly, I perceive.
What caused this is my stoopid little speaker test program that plays the US National Anthem (Star-Spangled Banner) that I shamelessly raped from some arduino app dev's git repo (credits are in the sources):
The SPK_defs.lib file:
Code: Select all
#ifndef SPK_defs
#define SPK_defs
'==============================================================================
' @file: SPK_lib.bas
' @target: ARMbasic v7 Target
' @language: ARMbasic
'
' This lib file provides #defs and other support data for making use
' of a spkr hooked to a GPIO line - in this case, it is a K1206 piezo buzzer actually
'
' @author Tod Wulff
' @version 1.1 - 12Aug18
' - Updated for current rev hardware
' @version 1.0 - 29Dec08
' - original version
'==============================================================================
'------------------------ IO Definitions --------------------------------------
#ifdef LPC824
#define _SPK_IO_PORT 6
#elif defined LPC54102 ' ARMdrino | ARMniobe
#define _SPK_IO_PORT 30
#endif
#endif
Code: Select all
#ifndef SPK_support
#define SPK_support
#include "spk\SPK_defs.lib"
'==============================================================================
' @file: SPK_lib.bas
' @target: ARMbasic circa 2018 Targets
' @language: ARMbasic
'
' This lib file provides support routines for making use of a speaker hooked to
' a GPIO line - in this case, it is a K1206 piezo buzzer actually...
'
' @author Tod Wulff
' @version 1.1 - 12Aug18
' Revised circa 2008 code for use with circa 2018 ARMbasic devices from Coridium
' This revision effort led me to understand that each device type has different timing models.
' and that I will need to revise this for additional devices, beyond the LPC800-DIP (w/ LPC824).
' @version 1.0 - 29Dec08
' - original version
'==============================================================================
' Preprocessor used to assert hard-coded constants vs using variables
#define _SPK_SwpHiFreq 5000
#define _SPK_SwpLoFreq 0
#define _SPK_SwpFreqLoopStep 100
#define _SPK_SwpMaxVol 20
#define _SPK_SwpMinVol 0
#define _SPK_SwpVolStep _SPK_SwpMaxVol
#define _SPK_SwpDur 1 'mS
#define bleep spk_beep(1500,15,25)
#define bloop spk_beep(500,15,25)
#define blip spk_beep(10000,1,1)
' FREQ 0-10,000HZ, VOL 0-50, Dur in uS
function spk_beep(spk_beep_freq as integer, spk_beep_volume as integer, spk_beep_duration as integer) as integer
'print spk_beep_freq, spk_beep_volume, spk_beep_duration
if(if((spk_beep_freq<=0)+(spk_beep_freq>10000),1,0)+if((spk_beep_volume<=0)+(spk_beep_volume>50),1,0)+if(spk_beep_duration<=0,1,0)) then return 1
dim spk_beep_start, spk_pulse_start, spk_pulse_period, spk_pulse_hi, spk_pulse_lo as integer
spk_pulse_period = 1000000/spk_beep_freq
spk_pulse_hi = spk_beep_volume * (10000/spk_beep_freq)
spk_pulse_lo = spk_pulse_period-spk_pulse_hi
output(_SPK_IO_PORT)
spk_beep_start = timer
while timer-spk_beep_start < spk_beep_duration * 1000
'in-lined durations of 1-4 us to get best representation considering loop overheads
'on the 824. need to throw this code at the other family members with a scope and
'give it a bit more robustness (#def the diff targets' timing.).
if spk_pulse_hi=1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 0
elseif spk_pulse_hi=2
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 0
elseif spk_pulse_hi=3
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 0
elseif spk_pulse_hi=4
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 1
out(_SPK_IO_PORT) = 0
else
spk_pulse_start = timer
out(_SPK_IO_PORT) = 1
while timer - spk_pulse_start < spk_pulse_hi
loop
out(_SPK_IO_PORT) = 0
endif
spk_pulse_start = timer
while timer - spk_pulse_start < spk_pulse_lo
loop
loop
out(_SPK_IO_PORT) = 1
return 0
endfunction
sub spk_sweep()
dim freq_, vol_ as integer
FOR vol_ = _SPK_SwpMinVol TO _SPK_SwpMaxVol STEP _SPK_SwpVolStep
FOR freq_ = _SPK_SwpLoFreq TO _SPK_SwpHiFreq STEP _SPK_SwpFreqLoopStep
SPK_BEEP(freq_, vol_, _SPK_SwpDur)
NEXT freq_
FOR freq_ = _SPK_SwpHiFreq DOWNTO _SPK_SwpLoFreq STEP _SPK_SwpFreqLoopStep
SPK_BEEP(freq_, vol_, _SPK_SwpDur)
NEXT freq_
NEXT vol_
FOR vol_ = _SPK_SwpMaxVol DOWNTO _SPK_SwpMinVol STEP _SPK_SwpVolStep
FOR freq_ = _SPK_SwpLoFreq TO _SPK_SwpHiFreq STEP _SPK_SwpFreqLoopStep
SPK_BEEP(freq_, vol_, _SPK_SwpDur)
NEXT freq_
FOR freq_ = _SPK_SwpHiFreq DOWNTO _SPK_SwpLoFreq STEP _SPK_SwpFreqLoopStep
SPK_BEEP(freq_, vol_, _SPK_SwpDur)
NEXT freq_
NEXT vol_
endsub
#endif
Code: Select all
/*************************************************
* Public Constants, for making music
' credits: https://github.com/Jianan-Li/misc-arduino-sketches/tree/master/LEDMusicPlayer
*************************************************/
#define SPK_Mnotes 89 ' # of notes herein
#define nB0 31
#define nC1 33
#define nCS1 35
#define nD1 37
#define nDS1 39
#define nE1 41
#define nF1 44
#define nFS1 46
#define nG1 49
#define nGS1 52
#define nA1 55
#define nAS1 58
#define nB1 62
#define nC2 65
#define nCS2 69
#define nD2 73
#define nDS2 78
#define nE2 82
#define nF2 87
#define nFS2 93
#define nG2 98
#define nGS2 104
#define nA2 110
#define nAS2 117
#define nB2 123
#define nC3 131
#define nCS3 139
#define nD3 147
#define nDS3 156
#define nE3 165
#define nF3 175
#define nFS3 185
#define nG3 196
#define nGS3 208
#define nA3 220
#define nAS3 233
#define nB3 247
#define nC4 262
#define nCS4 277
#define nD4 294
#define nDS4 311
#define nE4 330
#define nF4 349
#define nFS4 370
#define nG4 392
#define nGS4 415
#define nA4 440
#define nAS4 466
#define nB4 494
#define nC5 523
#define nCS5 554
#define nD5 587
#define nDS5 622
#define nE5 659
#define nF5 698
#define nFS5 740
#define nG5 784
#define nGS5 831
#define nA5 880
#define nAS5 932
#define nB5 988
#define nC6 1047
#define nCS6 1109
#define nD6 1175
#define nDS6 1245
#define nE6 1319
#define nF6 1397
#define nFS6 1480
#define nG6 1568
#define nGS6 1661
#define nA6 1760
#define nAS6 1865
#define nB6 1976
#define nC7 2093
#define nCS7 2217
#define nD7 2349
#define nDS7 2489
#define nE7 2637
#define nF7 2794
#define nFS7 2960
#define nG7 3136
#define nGS7 3322
#define nA7 3520
#define nAS7 3729
#define nB7 3951
#define nC8 4186
#define nCS8 4435
#define nD8 4699
#define nDS8 4978
Code: Select all
' credits: https://github.com/Jianan-Li/misc-arduino-sketches/tree/master/LEDMusicPlayer
' plays the star spangled banner
#include "spk\SPK_support.lib"
#include "spk\SPK_notes.lib"
sub playmelody
'76 elements
const SPK_Mfreqs = {
nF5,nD5,nAS4,nD5,nF5,nAS5,nD6,nC6,nAS5,nD5,nE5,nF5,
nF5,nF5,nD6,nC6,nAS5,nA5,nG5,nA5,nAS5,nAS5,nF5,nD5,nAS4,
nD6,nD6,nD6,nDS6,nF6,nF6,nDS6,nD6,nC6,nD6,nDS6,nDS6,
nDS6,nD6,nC6,nAS5,nA5,nG5,nA5,nAS5,nD5,nE5,nF5,
nF5,nAS5,nAS5,nAS5,nA5,nG5,nG5,nG5,nC6,nDS6,nD6,nC6,nAS5,nAS5,nA5,
nF5,nF5,nAS5,nC6,nD6,nDS6,nF6,nAS5,nC6,nD6,nDS6,nC6,nAS5
}
'76 elements - durations: 2 = half note, and 8/3,4,6,8,12
const SPK_Mdurations = {
6.0,12.0, 4.0, 4.0, 4.0, 2.0, 6.0,12.0, 4.0, 4.0, 4.0, 2.0,
8.0, 8.0, 2.76, 8.0, 4.0, 2.0, 8.0, 8.0, 4.0, 4.0, 4.0, 4.0, 4.0,
6.0,12.0, 4.0, 4.0, 4.0, 2.0, 8.0, 8.0, 4.0, 4.0, 4.0, 2.0,
4.0, 2.76, 8.0, 4.0, 2.0, 8.0, 8.0, 4.0, 4.0, 4.0, 2.0,
4.0, 4.0, 4.0, 8.0, 8.0, 4.0, 4.0, 4.0, 4.0, 8.0, 8.0, 8.0, 8.0, 4.0, 4.0,
8.0, 8.0, 2.76, 8.0, 8.0, 8.0, 2.0, 8.0, 8.0, 4.0, 4.0, 4.0, 2.0
}'over the land of the free and the home of the brave
#define SPK_Melements (76-1) ' the -1 adjust to a zero reference
#define SPM_MdefTempo 1500.0 'default tempo for this piece is 3000 - this is a denominator (larger # = slower tempo)
#define SPM_Volume 1 ' 1 to 50 - a pseudo pwm approach - 25 a is 50% duty cycle.
dim i as integer
dim SPK_Mnote_duration as single
for i= 0 to SPK_Melements
SPK_Mnote_duration = SPM_MdefTempo/SPK_Mdurations(i)
SPK_BEEP(SPK_Mfreqs(i), SPM_Volume, (1*SPK_Mnote_duration))
wait(SPM_MdefTempo/SPK_Mdurations(i)*1.3)
out(32)=i and 1 'toggle the LED state with each note
print chr(if(i mod 2 = 0,"+","*")); '~
next i
endsub
MAIN:
output(32) ' i've an LED hooked to this gpio for visual feedback purposes only
playmelody
END
Code: Select all
#include "spk\SPK_support.lib"
MAIN:
dim int, freq_, vol_, dur_, lastfreq, lastvol, lastdur as integer
lastfreq = -1
lastvol = -1
lastdur = -1
'spk_sweep
DO
Print "Enter Freq (INT, 0-10000, <0 to exit): ";
Debugin Freq_
if Freq_ < 0 then exit
if freq_ = 0 then freq_=if(lastfreq = -1, 2500, lastfreq) ' default to 2500 or last freq
Print Freq_;" Enter Volume (INT, 0-50): ";
Debugin Vol_
if Vol_ = 0 then Vol_=if(lastvol = -1, 25, lastvol) ' default to 25 or last volume
Print Vol_;" Enter Duration in MS (INT >0): ";
Debugin Dur_
if Dur_ = 0 then Dur_=if(lastdur = -1, 500, lastdur) ' default to 500 or last duration
Print Dur_
Print
doit:
if(SPK_BEEP(FREQ_, VOL_, DUR_)) then Print "Error!"
LastFreq = freq_
LastDur = dur_
lastvol= vol_
Print
Print
LOOP
bloop
bleep
bloop
bloop
bleep
bloop
bloop
bleep
bloop
END
Please advise if a sizeof exists and, if not, suggest a robust means to test an array to determine the # of elements. Thanks, in advance.
-t