page 1 Audio Documentation audio.scr

advertisement
page 1
Audio Documentation
The audio.scr program is used to control the frequency and decibels of the tone used for
classical conditioning. For example, discrimination training using either different tone frequencies or the
same tone with different decibel intensities could be given. The file also includes a program to measure
the tuning curve of neural activity of a single (or multiple) unit. Normally, tuning curves are made to find
the response of a single cell (single unit recording) to a range of frequencies, but a tuning curve could also
be made for a population of cells (multiple unit recording). This file is especially used in conjunction with
the hardware described in Chapters M (Forth interface card), N (The auditory stimulus) and J (Electrodes,
neural recordings and neural unit discriminator). The Runtime program (Appendix A, Runtime program in
Forth and 8088 assembly language; the file runtime.scr) includes documentation for the hardware
configuration and use of portd (frequency selection) and porte (decibel attenuator).
The formal documentation for loading and using the audio programs follows. These programs
were written with the idea of performing tuning curve experiments. In tuning curve experiments, the goal
is to characterize how a neuron or group of neurons reacts to various frequencies of tones. Usually, a
particular cell will respond vigorously or be inhibited within a certain frequency range. The tuning curve
programs have a number of options, one being to sample a cell's responses to a particular tone
(pitch/frequency) and then systematically test other tones, all at the same intensity (loudness). The same
progression of tones can then be tested at different intensities. Following the information here about
using the programs will be found the documentation for the actual program source codes.
Tuning Curve Documentation
The tuning curve software is contained in the file audio.scr which is used in conjunction with the
normal runtime software, forth.com. To use the audio functions, you need the files audio.scr, forth.com
and assemble.rlf. The latter file is needed to assemble the machine language code found in the
audio.scr file.
The tuning curve software allows the user to select tone frequencies between 0.5 kHz and 20 kHz
in 1 kHz increments, to select decibel attenuation from 0 to 127.5 dB reduction in 0.5 dB incrementes, to
turn on and off tones, and to collect unit counts to auditory evoked potentials. This software requires the
"forth" interface board (really a general-purpose interface board), and two hardware boards, one for
creating tone frequencies and the other for effecting the decibel attenuator. The "forth" board must have a
second 8255 chip which controls the two hardware boards.
Loading the Audio Functions
Boot up the normal runtime software. At the runtime opening menu, select the hidden 0 (zero)
option to exit the menu, and type flush<return> to close the menu file. Pressing <return> should result in
an OK reply, indicating that you are in the forth interpretter. Type including audio<return> to load in the
audio functions. An OK will appear when these have finished loading. You now have access to forth
commands to control the two boards, the frequency selector and decibel attenuator.
Frequency Commands
The default condition when forth boots up is a 1 kHz tone with no attenuation. The actual
loudness depends upon the setting of the volume on the audio amplifier. Normally for classical eyelid
conditioning this volume is adjusted to 85 dB SPL (decibels sound pressure level). You can always go
back to this default condition by typing reset<return>. To select another frequency, for example 7 kHz,
you would type 7. khz<return>. Notice that the spaces and decimal place in the number are necessary
for this to work correctly. You can select frequencies in the range of 0.5, 1., 2., 3. ... to 20. kHz. You will
not hear anything at this point. To hear the tone type y<return> and to turn it off type n<return>
abbreviations for yes-tone and no-tone.
Attenuation Commands
page 2
The default condition when forth boots up is a 1 kHz tone with no attenuation. The actual
loudness depends upon the setting of the volume on the audio amplifier. Normally for classical eyelid
conditioning this volume is adjusted to 85 dB SPL (decibels sound pressure level). You can always go
back to this default condition by typing reset<return>. There are two kinds of attenuation commands.
The first kind operates directly on the dB attenuator. The second kind operates indirectly on the dB
attenuation, taking into consideration the properties of the speaker being used. In this section, we will first
describe the direct commands, then have a discussion of speakers, and then talk about the indirect
commands. Note that the indirect commands are the more important ones for the casual user of this
software, and that you can skip over the direct commands to the section on speakers.
The indirect
attenuation commands require that you understand the fundamental limitation of speakers.
Direct attenuator commands. To reduce or attenuate the loudness by 15 decibels from the
original intensity, for example, you type 15. db!<return>. Notice that the spaces and decimal place in the
number are necessary for this to work correctly. To reduce or attenuate the loudness by 5 more decibels,
or a total of 20 dB from the original intensity, you type 20. db!<return>. Notice that the function db!
always operates on the original intensity when no attenuation is effects, i.e., from the reset condition.
Another way to get to the reset condition is to type 0. db!<return> which is probably the most useful
command to know in this paragraph.
Speakers. Speakers have the property of showing differential frequency responses. To get a
feeling for this property, let's consider 5 different frequencies: 1, 4, 8, 12 and 16 kHz. In our example,
each of these frequencies is electronically given the same amplitude of 1 volt peak-to-peak. The actual
voltage is not important here; what is important is that they all have the same amplitude going into the
speaker. But the speaker does not react equally to each frequency. In our example, the same input
amplitude into the speaker results in different sound intensities emitted from the speaker: 85, 89, 86, 73
and 79 dB respectively in this example. By the way, these are actual values that I measured with the B&K
decibel meter set on A weighting and slow response. If I were to use the command 15. db!<return> as
given above, the subsequent measured decibel intensities would be 70, 74, 71, 58 and 64 dB respectively.
That is ok if that is what you want. But for tuning curve measurements we want to change the frequency
while keeping the same intensity.
To keep the sound intensity the same no matter what frequency we are using we need to enter
the properties of the speaker into a table. This table is used by the indirect attenuator commands to
compensate for the speaker. To see this table type .c<return> which in Forth language is pronounced
"dot c", the "dot" being a Forth abbreviation meaning "print", so it could also be read as "print c" or "print
corrections".
To change this correction table, type correct<return> and have the dB meter ready to measure
the actual dB output of the speaker at each of the possible frequencies. The dB meter should be oriented
to the speaker like the subject and set to A weighting and slow response. Before or after you do this, you
could measure the ambient sound level when there is no tone, just for your own information. Write it
down; you never know when you may need it. On the day of the measurements I made for this write-up,
the background noise level was 53.5 dB with the door to the chamber closed and tightened shut; you can
see the meter reading through the observation window if you orient the meter correctly.
At each frequency, enter the measured decibels and press <return>. If for some reason you
make a mistake, press <escape> or press <return> without any number and the correction process will
stop. This is a temporary change  as soon as you leave the forth program or turn off the power your
changes are forgotten. To permanently keep these changes you need to edit the table in the audio.scr
file. To do this, type using audio<return> 4 edit<return> and edit the table called correction that you find
on that screen. When you are finished editing type ^n to save the changes and leave the editing mode.
Type flush<return> to close the file.
The command speaker<return> is like correct except that it
allows you to step through the different frequencies and listen to them without entering them into the
correction table. Like correct, speaker stops at each frequency, but instead of entering a number you
press any key to go on to the next frequency, or press <escape> to quit.
For reasons that will become apparent, if you are going to test with the tuning curve commands, it
is best to increase the volume of the audio amplifier so that every frequency produces a loudness of at
least some minimum number of decibels. For example, if all tones are to be tested at 80 dB, then no tone
should be less than 80 in the correction table. If any tone is lower than 80 in the correction table, then
page 3
increase the volume of all frequencies by turning up the volume knob on the audio amplifier until the
offending tone is at least 80 dB. Some of the other tones can get really loud  I measured one at about
111 dB  but remember that with the indirect commands you will reduce all tones to 80 dB for actual
presentation, in this example, so you do not have to worry about damaging the subject's ears or your
speaker.
If it is true that the relation between the decibels at different frequencies stays the same from day
to day and if the overall intensity changes from day to day, for example the volume knob on the audio
amplifier is moved, then it is possible to calibrate all the frequencies by making a correction to the audio
table that is relatively simple. Notice that I do not know that this is true; we need empirical data on this
question. But if it is true then I have the solution.
Here is the scenario. The decibel relationship between frequencies is determined to be reliable.
The lowest decibel reading in your correction table is, let's say for sake of argument, 84 dB at 18 kHz.
Remeber you can review this table by using the .c command. Let's say that we want all frequencies to be
at least 90 dB. Use the commands 18. khz 0. db!<return> y<return> to activate 18 kHz with no
attenuation, and adjust the volume knob until you read 90 dB on the dB meter. Turn the sound off with
n<return>. Now, to automatically make the correction to all frequencies in the correction table, type 18.
khz 90 db standardize<return>. You can check that all the frequencies have been increased by 6 dB
(the difference between 90 and 84 dB at 18 kHz) by using the .c command. It is important to notice that in
this command you do not use the command spl. If you do use that command you will get an error
message saying that you are trying to make the 18 kHz tone louder than the speaker is capable of (at the
original volume adjustment on the audio amplier; the software does not know that you changed the
volume knob) and the correction table will not be changed. If you type standardize<return> one more
time the table will be changed.
Indirect attenuator commands. To give an 80 decibel sound using the indirect commands you
use the command 80 db spl<return>. Notice that there is no decimal point after the number 80.
The indirect attenuator commands work by reading the associated value found in the correction
table for the requested frequency, and adjusts the decibel attenuation accordingly. For example, if you
wish to deliver a 2.0 kHz tone at 80 dB (the full commands would be 2. kHz 80 db spl<return>
y<return>) and the correction table holds the value 92, then the attenuator must subtract 12 dB from 92 in
order to achieve 80 dB. To next select 80 dB at 1.0 kHz you type 1. kHz 80 db spl<return> y<return>. If
you should ask for a decibel level that is greater than possible for that frequency then you will get an error
message.
This point bears repeating. It is very important to understand that the attenuator does just that 
it attenuates. Therefore, when using the indirect attenuator commands, you will get an error message if
you attempt to ask that a frequency be louder than it can possibly be. In the above example, there is no
way to deliver a 2. kHz tone that is louder than 92 decibels.
To make sure that the correction table is working properly at, say, 80 db, you can type the
command 80 db spl check<return> which is like the speaker command in that it steps through each of
the frequencies. Check, however, reads the correction table and sets each frequency to 80 decibels, in
this example. This makes checking the correction table fairly easy, since the decibel meter can be set at
just one dB range, here at the 80 dB range, so you do not have to keep going in and out of the chamber to
adjust the decibel meter.
A disadvantage of using the check command is that you have to step through all the frequencies
and enter their values into the correction table. Suppose you only want to change one or two values?
Then use the fix command as in 4. khz fix<return> to change the correction table for just 4 kHz. You are
asked to enter a new decibel value at that frequency. Once you choose the frequency (here 4. khz) you
can repeat fix<return> as many times as you like without having to reenter the frequency. You can
choose not to make a change by pressing <escape> or by entering a nonnumber<return>. In any event,
you can then look at the correction table with .c command to see that the change has been made or step
through the frequencies with the check command to hear that the change has been made.
The difference. The difference between the direct and indirect commands is the following. The
direct command operates directly on the dB attenuator. Therefore, the number associated with the direct
command db! represents how many decibels are subtracted from the maximum output of the speaker at
page 4
that frequency. For the example of 2.0 kHz above, the maximum speaker output is given as 92 dB. To
reduce that to 80 dB you would use the command 12. db!<return>. The output of the speaker is now 80
dB.
The indirect command operates on the dB attenuator only after checking the correction table. For
the 2.0 kHz example above, the indirect command 80 db spl<return> results in the same 80 dB output of
the speaker. The tuning curve command called "test" below makes use of the indirect commands.
Tuning Curve Commands
More than likely you will not use either the direct or indirect commands above. Instead you will
use either the white noise, test or octave commands given here. Here we give a very brief descript of the
three commands, and then discuss their common properties. All these commands count the number of
spikes before, during and after stimulus delivery, and also report the difference by subtracting out the
before (baseline) count. See the attached print out.
White Noise. When you have isolated a unit and you wish to see if it has any auditory response
then you would use the command white noise<return> or simply noise<return> This command will
cause a white noise stimulus (see Important Note) to be delivered for several trials and for units to be
counted on unit channel 1 of the forth interface board. The wire for the white noise source must be
hooked up to the rise/fall switch. The attenuator is not used so the sound is as loud as it can be. The
data output of the noise command would be one line of the same data format that is seen with the test
command. See Figure 1 for a simulated print out of the test command.
Test. This is the main tuning curve command. To use it, indicate the indirect decibel level for the
test and issue the command. For example, to give a series of trials at 85 decibels for every frequency use
the command 85 db spl test<return> If this 85 dB level is higher than the ability of the speaker to deliver
that intensity, as determined by the correction table you created with the correct command, then the test
will quit. This command will cause a tone stimulus (see Important Note) to be delivered for several trials
and for units to be counted on unit channel 1 of the forth interface board. Obviously, the wire for the tone
generator must be hooked up to the rise/fall switch. These tones are 0.5, 1.0, 2.0, 3.0, 4.0, 5.0 6.0, 7.0,
8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0 and 20.0 kHz in this order. See Figure 1
for a simulated print out of the test command.
Octave. This could be an alternative to using white noise to sample if a cell is responsive to an
auditory stimulus, but like test this command it delivers tones at the specified decibel intensity. To use it,
indicate the indirect decibel level for the octave and issue the command. For example, to give a series of
trials at 85 decibels for every frequency use the command 85 db spl octave<return>. If this 85 dB level
is higher than the ability of the speaker to deliver that intensity, as determined by the correction table you
created with the correct command, then the octave will quit. This command will cause a tone stimulus
(see Important Note) to be delivered for several trials and for units to be counted on unit channel 1 of the
forth interface board. Obviously, the wire for the tone generator must be hooked up to the rise/fall switch.
These tones are 0.5, 1.0, 2.0, 4.0, 8.0, and 16.0 kHz in this order. See Figure 1 for a simulated print out of
the test command.
Common properties. The white noise, test and octave commands use several common
variables, values, switches and exiting properties.
The number of trials depends on the value of the variable #t/blk (number of trials per block). The
default is 20. Each trial consists of four (4) periods, 1, 2, 3 and 4, which correspond to baseline (1), tone
on (2), tone off (3), and another tone off period which could also be considered to be the intertrial interval
(4). The default value is 200 msec for each period, for a total of 800 msec (0.8 sec) for each trial. This
duration is determined by the binwidth and the total number of points for each period. The default values
are 10000 sec for the binwidth and 20 for the number of points: 10000 times 20 is 200 msec. These
default values are now in the word change  to alter the defaults you must edit the audio.scr file (see
Warning below).
I repeat: you now have to edit the command change to alter these default values. When you edit
that definition, to change the binwidth to 5 msec, use the command 5000 bin ! (notice that 5000 sec is
page 5
the same as 5 msec). To change the number of points to 10, use the command 10 is pts. Bin, like #t/blk,
is a forth variable so you use the forth ! point to change it. Pts is a forth value, which is like a soft constant
(a term I just made up, but means that it usually stays a certain value but that it can change if need be), so
it uses the forth command is to change. The resulting period duration for these two changes would be
5000 times 10, or 50 msec. You also change the number of trials per block here (for example, 5 #t/blk !
causes only 5 trials per block). Remember that these are permanent changes when you edit the correct
screen of the audio.scr file. See the Warning that follows.
WARNING: The variables bin and #t/blk and the value pts are used by the
runtime and summary programs. Since they are used by the audio program also there
was a conflict between using the audio program and the runtime and summary programs;
meaning, for example, that if you interrupt running classical conditioning trials using the
editor <escape> option to use noise or test and then return to classical conditioning by
pressing <return> or typing continue<return> that your classical conditioning program
will now use the audio parameters and soon cause the computer to crash. You could
have avoided this problem by using menu<return> to restart classical conditioning where
you left off.
However, in the interest of user friendliness, the commands noise, test, and
octave have been changed so that they save the runtime values, change to fixed audio
values, run their respective functions, and then restore the original runtime values. This
housekeeping is done transparently, without any awareness by the user. The advantage
of this is that there is reduced conflict between the runtime and audio programs. The
disadvantage is that it becomes difficult to change the parameters for the audio program.
To change the parameters for the audio program, you need to edit the screen in
the audio program which has the definition for the word change. This is currently on
screen 16, but that could change in future versions, so you would have to search through
the file to find it. To alter the definition of change at this time, you would type using
audio<return>16 edit<return>, make your alterations to the definition of change, and
type ^n followed by flush<return>.
To get a print out of the white noise or test results type printing on<return> before you invoke
those trials. The default printing off<return> turns the printer off. The word printing is a switch, meaning
that it is a variable that only takes on values of on or off.
Each of the commands white noise, test and octave will automatically go through the specified
number of trials (#t/blk) without pause. You cannot stop this once it has started.
The commands test and octave additionally step through their respective tone frequencies. It is at
this point that you can interrupt the progression by pressing any key to pause and restart by pressing any
key except <return>. If you press <return> as the second key then you stop the progression entirely. An
easy way to think of this is if you want to stop test or octave, just press <return><return> at any time and
wait for the tones to stop when they would have changed values. Remember: the test and octave
commands will continue to give tones at the same frequency; it is only when there is a transition from one
frequency to the next higher frequency that they pay attention to the keys you pressed and either pause or
abort.
Important Note. The audio frequency board does not have a white noise generator on it. For the
audio white noise commands to work properly, you must hook up a white noise source to the rise/fall
switch on the interface equipment. You must also remember to change the wire back to the frequency
source when you use the test commands.
page 6
Periods 1, 2, 3, 4 == baseline, tone on, tone off 1, tone off 2/intertrial interval.
Each period equals 200 msec.
Each frequency accumulates over 20 trials.
Counts for
Period
1
1
2
3
4
120
125
115
119
118
122
118
118
.
.
.
.
.
.
.
.
.
.
.
.
.
115
148
189
257
167
132
120
119
.
.
.
.
.
.
.
.
.
.
.
.
.
127
110
110
132
103
118
118
119
.
.
.
.
.
.
.
.
.
.
.
.
.
123
124
103
121
122
122
119
117
.
.
.
.
.
.
.
.
.
.
.
.
.
kHz at 70 dB
0.5
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0
13.0
14.0
15.0
16.0
17.0
18.0
19.0
20.0
Differences for
Period 2-1
-5
23
74
138
49
10
2
1
.
.
.
.
.
.
.
.
.
.
.
.
.
Period 3-1
7
-15
-5
13
-15
-4
0
0
.
.
.
.
.
.
.
.
.
.
.
.
.
Period 4-
3
-1
-12
2
4
0
1
-1
.
.
.
.
.
.
.
.
.
.
.
.
.
Figure 1. Simulated print out of audio test command. Each line is the accumulation of all unit counts in
each period for 20 trials. The full commands for this print out would be including audio<return>
10000 bin ! <return> 20 is pts <return> 20 #t/blk !<return> 70 db spl test<return>, but since
these are default values all you really need to use is including audio<return> 70 db spl
test<return> which is what I actually used here [the numbers in the periods are made-up]. Note
that you can leave out all the <return>s except the very last one. Additional testing could be
continued with, for example, 60 db spl test<return> and 50 db spl test<return>; in other words,
you only need to use the command including audio<return> once, unless you leave Forth or turn
off the power in between.
page 7
Audio source code
The following is the source code for the audio programs.
One of the main features of the audio.scr program is the correction table. Speakers and
electronics behave differently in terms of decibels for different frequencies. The experimenter enters into
the correction table the actual decibels measured for each given frequency. This information is then
used to adjust the decibels, through the attenuator, so that when a particular decibel level is given then all
frequencies of tone will have the same loudness automatically. For example, after entering 85 db
spl<return>, all tones will be 85 decibels. Increasing or decreasing the decibels will automatically adjust
all the frequencies to the same loudness. By these means, a progressive series of tones can all be given
at the same decibel value. Any changes in neural responses to the stimuli must be due to the differences
in frequencies, not to the loudness because that has been compensated. Since the loudness is
manipulated with an attenuator, it must be noted that only corrections that decrease the intensity of the
sound are possible. That is, if 85 decibels is required but the frequency was only measured to give 79
decibels, then the attenuator will be of no help. Special commands are included for setting up the
correction table.
The audio.scr file includes the command test<return> which is used to automatically collect unit
1 data for a tuning curve. All frequencies on the interface (0.5, 1.0, 2.0, 3.0 ... 20.0 kHz) are successively
tested at a given decibel level. For example, 70 db spl test<return> measures unit responses to all the
tones at 70 decibels. Each tone is given 20 times and the unit activity accumulated over those 20 trials.
Activity is measured just before the tone (baseline), during the tone, and for two periods after the tone is
turned off. All four periods are the same duration. Typical durations are 50 or 200 msec for each period.
The end of the audio.scr file includes new trial type definitions that can be incorporated into a trial
sequence for the Runtime program. For example, discrimination training between tone different tones of
the same intensity can be trained with the sequence
: discrimination ( --) >s slip cs+ cs+a cs- cs- a& cs+a cs+a cs- cs+a cs- ;
and resolved in the menus.scr (Appendix B) file as
' discrimination is trialsequence
where cs+ is the stimulus that is paired with an airpuff most of the time (cs+a) and cs- is the stimulus that
is never paired with an airpuff. Test trials of the stimuli by themselves are also included. In the file
audio.scr the cs+ is a 1 kHz tone and cs- is a 2 kHz tone, both at 85 dB, but any of these values can be
defined within the parameters of the audio program.
As with the other programs in these appendices, this file has been modified in the following ways:
comments have been expanded; screens have been idenfified by numbers; codes and comments used
for debugging have been removed to avoid confusion (for example, we have edited out all the double
number routines); screens have been combined when their separation served no compilation or
documentary purpose; and for documentation instructions have been included as comments.
\ screen 0
\ AUDIO.SCR file
\
\ based on HEATH.SCR file
\
\ this file contains words for using:
\ 1. the computer controlled frequency generator through the improved IBM parallel interface.
\ 2. the computer controlled decibel attenuator through the improved IBM parallel interface.
\
\ notes: 8255 # 2 must be installed on the Forth board. Runtime software already initializes the chip
\ whether it is there or not.
\
\ use: 12. khz 85 db spl -- sets 12 khz at 85 db with compensation for speaker (uses correction table).
page 8
\
\ 04oct99 constant sample for epoch durations
\
\ This version of Forth has the following bugs ...
\ 1. valid dn = 1.0, 1., 1.5 will all give 1 khz.
\ 2. compiled dn's do not always set 1 DPL !
\ screen 1
\ this screen controls all loading of the audio routines.
decimal
need audio not \if forget audio
create audio
need printing \if variable printing
transient
reloading assembler
resident
: y ( --)
\ shorthand for 'yes, turn on tone'.
1 portb pc! ;
: n ( --)
\ shorthand for 'no, turn off tone'.
0 portb pc! ;
: rr ( --)
\ shorthand for a more pleasant sounding warning: beep! beep!
\ only works well with older, slower computers.
roadrunner ;
: c+! ( b adr --)
\ byte equiv of Forth +!.
cr
tuck c@ + swap c! ;
2 size 1- thru
\ loading audio interface words.
decimal
dispose
\ removes transient assembler.
\ screen 2
\ frequency table
\ this table refers to the output pattern on 8255#2 portd for controlling frequency selection.
\ see runtime.scr for documentation.
create frequencies
binary ( lower frequencies ...)
00001 c, ( .5kHz) 00000 c, ( 1kHz) 00010 c, ( 2kHz)
00011 c, ( 3kHz) 00100 c, ( 4kHz) 00101 c, ( 5kHz)
00110 c, ( 6kHz) 00111 c, ( 7kHz) 01000 c, ( 8kHz)
01001 c, ( 9kHz)
page 9
binary ( higher frequencies ...)
10000 c, ( 10kHz) 10001 c, ( 11kHz) 10010 c, ( 12kHz)
10011 c, ( 13kHz) 10100 c, ( 14kHz) 10101 c, ( 15kHz)
10110 c, ( 16kHz) 10111 c, ( 17kHz) 11000 c, ( 18kHz)
11001 c, ( 19kHz) 11010 c, ( 20kHz)
decimal
\ screen 3
\ frequency words
: (khz) ( dn--n)
\ takes a double number for the desired kHz and converts it to an index for the frequencies table.
drop dpl @
if
10 /mod dup 0=
if
swap 5 = if drop 0 then
else
nip
then
then ;
variable pointer 1 pointer !
\ default is 1 KHz.
: khz ( dn --)
\ selects specified frequency.
\ this is an absolute command: requesting 5.0 khz causes 5 kHz tone.
\ use: 1.0 khz<return>.
(khz)
0 max 20 min ( range check)
pointer !
pointer @ frequencies + c@ portd pc! ;
: +khz ( dn --)
\ advances frequency by specified double number.
\ this is a relative command: requesting 1.0 +khz causes the current frequency to increase by 1 kHz.
\ use: 1.0 +khz<return>
\ used mostly for automatically advancing through frequencies table when setting decibels.
(khz)
pointer @ + 20 min ( range check)
dup pointer ! frequencies + c@ portd pc! ;
: -khz ( dn --)
\ retreats frequency by specified double number.
\ this is a relative command: requesting 1.0 -khz causes the current frequency to decrease by 1 kHz.
\ use: 1.0 -khz<return>
\ complementary function to +khz. not used.
(khz)
pointer @ swap - 0 max ( range check)
dup pointer ! frequencies + c@ portd pc! ;
\ screen 4
\ dB correction table for speaker ...
\ this table refers to the output pattern on 8255#2 for controlling decibel attenuation selection.
\ see runtime.scr for documentation.
page 10
\ entries are put into this table to indicate, for example, that when a 2 kHz tone was given it was
\ measured as being 96 dB loud.
\ this information is used to equate all tone frequencies to the same decibel level by
\ using the attenuator to lower higher decibel tones.
\ this means that the lowest decibels in this table is a limiting condition.
create correction
\ explicit decimal declaration in parentheses are for documentation only.
\ 30W tweeter spkr w/84 dB at 18 khz; background noise measured at 53.5 dB.
85 c, ( .5kHz) 85 c, ( 1kHz) 96 c, ( 2kHz) 85 c, ( 3kHz) 85 c, ( 4kHz) 95 c, ( 5kHz) 85 c, ( 6kHz)
85 c, ( 7kHz) 85 c, ( 8kHz) 85 c, ( 9kHz) 85 c, ( 10kHz) 85 c, ( 11kHz) 85 c, ( 12kHz) 85 c, ( 13kHz)
85 c, ( 14kHz) 85 c, ( 15kHz) 85 c, ( 16kHz) 85 c, ( 17kHz) 85 c, ( 18kHz) 85 c, ( 19kHz)
85 c, ( 20kHz)
\ Correction table is used to compensate for the actual frequency response of the speaker being used.
\ This must be determined before the experiment. After using this table, every frequency will give the
\ SAME loudness with that speaker.
\ screen 5
\ print correction table
: .c ( --)
\ print correction table.
printing @ if printer on 15 emit then
cr ." Freq dB"
21 ( to) 0 ( fr)
do
cr i s>d 4 d.r ( .index)
correction i + c@ s>d 4 d.r ( .dB)
nuf? ?leave
loop
printing @ if cr printer off then ;
\ screen 6
\ decibal manipulation
: (dB) ( n --)
\ figure out value using correction table to place on dB porte.
dpl @ ( evaluate decimal place)
if
dup ( n n) 10 / ( n w) ( set whole number)
1 <shift ( n 2*w) ( set for interface whole number)
swap ( 2*w n)
10 mod 5 = if 1+ ( 2*w') then
else
1 <shift
then ;
: dB! ( dn --)
\ 0. to 127.5 dB in 0.5 dB steps.
\ this is an absolute command: the decibels entered will be invoked.
drop (dB) porte pc! ;
: -dB! ( n --)
\ set absolute dB.
\ this is a relative command: lower decibels by n from current value.
page 11
(dB) porte pc@ + porte pc! ;
: +dB! ( n --)
\ set relative -dB.
\ this is a relative command: increase decibels by n from current value.
(dB) porte pc@ swap - porte pc! ;
: loud ( dn --)
\ increase or decrease decibels from current level to achieve double number value.
if
negate
-dB!
else
+dB!
then ;
\ screen 7
\
continued
variable dbls
\ dbls used to remember desired db level; used for parameter passing.
: dB ( n --)
\ an English-like notation.
\ use: 85 db spl<return>.
dbls ! ;
variable error
: spl ( --)
\ compensates for speaker and sets freq to dB level of dbls.
\ use: 85 db spl<return>.
pointer @ correction + c@ dbls @ dup 0<
\ abort" Cannot make sound louder"
if
true error !
else
false error !
then
s>d 0 dpl ! db! ( loud) ;
: .error ( --)
\ give warning when attenuator cannot make correction.
error @
if
5 spaces
." < INVALID DATA: Cannot make sound louder"
then
noop ;
\ screen 8
\ correct
: correct ( --)
\ step through tones and allows user to enter correct dB.
\ only change values that need to be changed.
page 12
\ USE: correct<return>
cr ." Enter decibels from B&K meter using A filter, slow."
cr ." Enter a non-number or <ESC> to abort"
cr ." WARNING: This is a temporary change. To make a permanent change, edit screen 4 and
save."
cr cr ." kHz"
0.5 1 dpl ! khz 0. 0 dpl ! dB! y
21 0
do
cr
pointer @
if
pointer @ s>d 4 d.r
else
." 0.5"
then
5 spaces
get$ val
if
drop pointer @ correction + c!
else
n abort
then
1.0 1 dpl ! +kHz
loop
n;
\ screen 9
\ speaker
: speaker ( --)
\ use to calibrate speaker.
\ USE: speaker<return>
\ step through frequencies and allow user to enter values; manually measure db; A filter, slow
\ all values must be entered.
cr ." Press any key to continue."
cr ." Press <esc> key to exit" cr
cr ." Freq"
0. 0 dpl ! dB! ( set no db loss)
0.5 1 dpl ! kHz ( start at 0.5 khz)
y ( turn tone on)
21 0
do
cr
pointer @
if
pointer @ s>d 4 d.r
else
." 0.5"
then
key esc# = if n ( turn tone off) leave then
1.0 1 dpl ! +kHz ( advance khz)
loop
n ( turn tone off) ;
\ screen 10
page 13
\ check
: check ( --)
\ use to check calibration of speaker.
\ USE: e.g., 80 db spl check<return>
\ use A filter, slow.
\ step through frequencies, automatically compensating for dB. all tones should be the same loudness.
cr ." Press any key to continue."
cr ." Press <esc> key to exit" cr
cr ." Freq"
0.5 1 dpl ! kHz spl ( start 0.5 khz w/compensated db)
y ( turn tone on)
21 0
do
cr
pointer @
if
pointer @ s>d 4 d.r
else
." 0.5"
then
key esc# = if n ( turn tone off) leave then
.error
1.0 1 dpl ! +kHz spl ( advance khz)
loop
n ( turn tone off) ;
\ screen 11
\ fix
: fix ( --)
\ to change correction table for a single frequency.
\ USE: n. khz fix<return>
\ used to correct a single value in the correction table.
cr
." Enter new value for "
pointer @ 0=
if
." 0.5 "
else
pointer @ u.
then
." kHz then press <return>"
3 spaces
get$ val
if
drop pointer @ correction + c!
else
n abort
then
noop ;
\ screen 12
\ drawcorrections
: drawcorrections ( --)
page 14
\ a graphical display showing the properties of the speaker at the different frequencies
\ i.e., the frequency response.
gr
21 ( to) 0 ( fr)
do
i 10 * ( x) 255 i correction + c@ - ( y)
i 0= if dot else line then
nuf? ?leave
loop ;
\ screen 13
\ unit#1 zero and read functions ...
\ the following code is used to collect data from unit 1: baseline, tone on, tone off, tone off.
\ this allows for tuning curve information to be collected from a single or multiple unit recording.
hex
: read ( -- n)
\ NOTE: n = word length (not byte length).
40 cw8253#1 pc! \ latch time1 ($00, 40, 80 = t0, t1, t2)
time1 pc@ ( lower byte)
time1 pc@ ( upper byte)
combine negate ;
: strobe ( --)
\ set count or increment counter.
portc pc@ dup 1+ portc pc! portc pc! ;
decimal
\ screen 14
\ zero and settimer0
: zero ( --)
\ enter 0 and strobe to set count.
0 time1 pc! 0 time1 pc!
strobe ;
code settimer0 ( --)
time0 # dx mov bin ) ax mov dx al out
ah al mov dx al out
next c;
\ setup isi tmr.
\ accumulators for the various periods ...
variable period1
\ baseline.
variable period2
\ tone on period.
variable period3
\ tone off period # 1.
variable period4
\ tone off period # 2.
: clearperiods ( --)
0 period1 !
0 period2 !
0 period3 !
0 period4 ! ;
\ screen 15
page 15
\ code word for tone evoked responses
hex
code epoch ( --)
' pts >body ) cx mov
0 # ax mov ax ' bin# >body ) mov
cli
1 l: portc # dx mov
2 l: dx al in 10 # al and 2 l# je
3 l: dx al in 10 # al and 3 l# jne
' bin# >body ) inc
1 l# loop
sti
next c;
\ setup isi cntr w/pts to collect.
\ zero isi cntr.
\ prevent interrupts.
\ sync ...
\ do stuff during each isi
\ allow interrupts.
decimal
\ screen 16
\ single trial
: evoke ( -- n1 n2 n3 n4)
\ one trial evoked potential ...
zero
epoch ( baseline)
read
zero
y ( tone on)
epoch ( onset response)
read
zero
n ( tone off)
epoch ( offset response)
read
zero
epoch ( extra)
read
noop ;
\ screen 17
\ save/restore bin and pts
\ temporary storage variables ...
variable bin'
variable #t/blk'
\ temporary storage constant ...
0 constant pts'
5 constant sample
\ active words ...
: save ( --)
\ save old (default) settings.
\ the purpose of this function is so that a tuning curve can be taken in the middle of a session.
\ the parameters for bin, pts and #t/blk are different for a tuning curve and a run of trials.
page 16
\ the parameters can be restored after the end of the tuning curve.
bin @ bin' ! pts is pts' #t/blk @ #t/blk' ! ;
: change ( --)
\ these are the new default settings for the tuning curve collection.
10000 bin !
sample is pts
20 #t/blk ! ;
: restore ( --)
\ return parameters to running trials.
bin' @ bin ! pts' is pts #t/blk' @ #t/blk ! ;
\ screen 18
\ multiple trials
: evokedpotentials ( --)
\ collect units from a bunch of trials (#t/blk) at the same frequency.
\ set khz and db before using evokedpotentials.
clearperiods
settimer0
#t/blk @ 0
do
evoke
period4 +!
period3 +!
period2 +!
period1 +!
loop
noop ;
\ screen 19
\ multiple trials
variable wn
wn off
\ white noise switch
: .periods ( --) 3 spaces
\ print the periods.
period1 @ s>d 5 d.r
period2 @ s>d 5 d.r
period3 @ s>d 5 d.r
period4 @ s>d 5 d.r
4 spaces
wn @
if
." noise" space
else
pointer @
if
pointer @ s>d 5 d.r ." .0"
else
4 spaces 5 s>d <# # ascii . hold #s #> type
then
then
10 spaces
page 17
period2 @ period1 @ - s>d 9 d.r
4 spaces
period3 @ period1 @ - s>d 7 d.r
4 spaces
period4 @ period1 @ - s>d 7 d.r
.error cr ;
\ screen 20
\ messages
: .message0 ( --)
cr
." Periods 1, 2, 3, 4 == baseline, tone on, tone off 1, tone off 2/intertrial interval." cr
." Each period equals " bin @ 1000 / pts * u. ." msec." cr
." Each frequency accumulates over " #t/blk @ u. ." trials."
cr cr ;
: .message1 ( --)
." Counts for " 32 spaces ." Differences for " cr
." Period 1 2 3 4 kHz @ "
wn @ if ." ??? db" else dbls @ u. ." dB" then
5 spaces ." Period 2-1 Period 3-1 Period 4-1 "
cr cr ;
\ screen 21
\ white noise
: white noop ;
: noise ( --)
\ use: white noise<return>
\
or noise<return>.
\ Note: set up white noise wire to rise/fall swith
save
change
cr ." Be sure to set up white noise wire for this test."
cr cr
printing @ if printer on 15 emit then
0. 0 dpl ! db!
.message1
evokedpotentials
wn on
.periods
wn off
printing @ if printer off then
restore ;
\ screen 22
\ test word
: test ( --)
\ this is the main execution word used to collect evoked potential data.
\ test steps through all frequencies in the table.
\ USE: 70 db spl test<return> test<return>
save
change
page 18
cr ." Be sure to set up tone wire for this test." cr cr
printing @ if printer on 15 emit ( condensed) then
.message0
.message1
0.5 1 dpl ! khz ( n db) spl evokedpotentials
.periods
20 0
do
1. 0 dpl ! +khz ( n db) spl
evokedpotentials
.periods
nuf? ?leave
loop
cr
roadrunner
printing @ if printer off then
restore ;
\ screen 23
\ octave
: octave ( --)
\ an alternative execution word to using test.
\ this word steps through available frequencies by octave (i.e., not all frequencies in table are used).
\ an octave is a doubling of the previous frequency.
\ USE: 70 db spl octave<return> octave<return>
save
change
cr ." Be sure to set up tone wire for this test." cr cr
printing @ if printer on 15 emit ( condensed) then
.message0
.message1
0.5 1 dpl ! khz ( n db) spl evokedpotentials
.periods
50
do
pointer @
\ double kHz each loop.
dup 0= if drop 1 then
\ 0.5 kHz is special condition.
s>d 0 dpl ! +khz ( n db) spl evokedpotentials
.periods
nuf? ?leave
loop
cr
roadrunner
printing @ if printer off then
restore ;
\ screen 24
\ standardize
: standardize ( --)
\ given khz, standardize all other db.
\ USE: 18. khz 90 db standardize<return>
\ i.e., bumps all freqs by same relative dB to set 18 khz at 90.
\ REM: you can use .c before and after to see table.
\ NOTE: do NOT use spl !!!
page 19
\ the following is from the definition of spl without abort ...
\
pointer @ correction + c@ dbls @ \
s>d 0 dpl ! db! ( loud)
\ the following is the routine for changing correction table ...
dbls @ pointer @ correction + c@ - ( difference)
21 0
do
dup i correction + c+!
loop
( difference) drop ;
\ screen 25
\ discrimination words
\ the following words are used to create new trial types that can be incorporated into the Runtime
\ program. These are similar to t&, t&a, &a etc.
: cs+ ( --)
\ a cs+ alone test trial.
1 0 0 dpl ! khz 85 dB spl iti tone trial ;
: cs+a ( --)
\ a cs+ and airpuff paired trial.
1 0 0 dpl ! khz 85 dB spl iti tone-air trial ;
: cs- ( --)
\ a cs- alone test trial.
2 0 0 dpl ! khz 85 dB spl iti tone trial ;
: cs-a ( --)
\ a cs- and airpuff paired trial.
2 0 0 dpl ! khz 85 dB spl iti tone-air trial ;
: cs-- ( --)
\ a cs- alone test trial. cs- is different here than above.
5 0 0 dpl ! khz 85 dB spl iti tone trial ;
: cs--a ( --)
\ a cs- and airpuff paired trial. cs- is different here than above.
5 0 0 dpl ! khz 85 dB spl iti tone-air trial ;
\ : discrimination ( --)
\ \ an example of a block of discrimination trials.
\
>s slip cs+ cs+a cs- cs- a& cs+a cs+a cs- cs+a cs- ;
\ screens 26 and 27
\ documentation
\ the following gives correct syntax for use through examples and their consequences.
\ a handly summary.
\
\
\ speaker<return>
\ to step through frequencies so that you can manually measure the dB response of the speaker.
\
\ correct<return>
\ to step through the frequencies AND enter measured dB response of the speaker.
\
page 20
\ .c<return>
\ to print out correction table.
\
\ 0. db!<return>
\ to set absolute value of db loss; NO dB loss.
\
\ 1. khz 85 db spl<return>
\ e.g., to set frequency and db level.
\
\ white noise<return> or noise<return>
\ to measure response to evoked stimulus.
\
\ 70 db spl test<return>
\ to acquire evoked potentials for all frequencies.
\
\70 db spl octave<return>
\ for evoked potentials to octave frequencies.
\
\ printing on<return>
\ to turn on printer.
\
\ drawcorrections<return>
\ to see graphic correction display.
\
\ 18. khz 89 db standardize<return>
\ changes 18 khz to be 89 in correction table, and modifies all other frequencies by same relative
\ amount.
\
\ 80 db spl check<return>
\ to check calibration of speaker.
\ steps through frequencies, automatically compensates for dB.
\
\ 5 is sample
\ causes each epoch to be 50 msec == default
\
\ 10 is sample
\ causes each epoch to be 100 msec
\
\ 20 is sample
\ causes each epoch to be 200 msec
Download