; DPOAEs
; Iain McCurdy, 2021
; INSTRUCTIONS
; Activate LISTEN for the Primary Tones
; Try to hear a 'phantom' distortion frequency otoacoustic emission.
; Click on each of the distortion products, Cubic or Quadratic to hear if this was one of the phantom frequecies you were hearing.
; F2 suggested between 2000 and 8000 Hz for diagnosis of hearing loss
; Ratio 1:2 tends to produce the most robust DPOAE
; Health is indicated at F2 location, not DPOAE frequency
form caption("DPOAEs") size(420, 220), pluginId("DOAE"), guiMode("queue"), colour(0,0,0,0)
image bounds( 5, 5,190,210), colour(0,0,0,0), outlineColour(100,100,100), outlineThickness(2)
{
label bounds( 5, 5,180, 15), text("Primary Tones")
nslider bounds( 5, 20, 80, 40), channel("F1"), range(0, 5000, 3164, 1, .1), text("F1 (Hz)")
nslider bounds(105, 20, 80, 40), channel("F2"), range(0, 5000, 3828, 1, .1), text("F2 (Hz)")
nslider bounds( 55, 60, 80, 40), channel("Ratio"), range(0, 5000, 0, 1, .001), text("Ratio")
nslider bounds( 5,100, 80, 40), channel("L1"), range(-90, 0, -20, 1, .1), text("L1 (dBfs)")
nslider bounds(105,100, 80, 40), channel("L2"), range(-90, 0, -20, 1, .1), text("L2 (dBfs)")
button bounds( 5,145, 80, 18), fontColour:0(150,100,100), fontColour:1(105, 5, 5), colour:0(10, 0, 0), colour:1(210,50,50), text("SOLO","SOLO"), channel("Solo1"), latched(1), value(0)
button bounds(105,145, 80, 18), fontColour:0(150,100,100), fontColour:1(105, 5, 5), colour:0(10, 0, 0), colour:1(210,50,50), text("SOLO","SOLO"), channel("Solo2"), latched(1), value(0)
button bounds( 55,170, 80, 30), fontColour:0(100,150,100), fontColour:1( 5,105, 5), colour:0( 0,10, 0), colour:1(110,210,110), text("LISTEN","LISTEN"), channel("Listen0"), latched(1), value(0)
}
image bounds(210, 5, 90,210), colour(0,0,0,0), outlineColour(100,100,100), outlineThickness(2)
{
label bounds( 5, 5, 80, 15), text("Cubic")
nslider bounds( 5, 20, 80, 40), channel("F3"), range(0, 5000, 210, 1, .1), text("2F1 - F2 (Hz)") ; cubic difference tone
nslider bounds( 5,100, 80, 40), channel("L3"), range(-90, 0, -20, 1, .1), text("L3 (dB)")
button bounds( 5,170, 80, 30), fontColour:0(100,150,100), fontColour:1( 5,105, 5), colour:0( 0,10, 0), colour:1(110,210,110), text("LISTEN","LISTEN"), channel("Listen3"), latched(1), value(0)
}
image bounds(320, 5, 90,210), colour(0,0,0,0), outlineColour(100,100,100), outlineThickness(2)
{
label bounds( 5, 5, 80, 15), text("Quadratic")
nslider bounds( 5, 20, 80, 40), channel("F4"), range(0, 5000, 210, 1, 0.1), text("F2 - F1 (Hz)") ; cubic difference tone
nslider bounds( 5,100, 80, 40), channel("L4"), range(-90, 0, -20, 1, .1), text("L4 (dB)")
button bounds( 5,170, 80, 30), fontColour:0(100,150,100), fontColour:1( 5,105, 5), colour:0( 0,10, 0), colour:1(110,210,110), text("LISTEN","LISTEN"), channel("Listen4"), latched(1), value(0)
}
-n -d -m0d
ksmps = 16
nchnls = 2
0dbfs = 1
instr 1
kF1 cabbageGetValue "F1"
kF2 cabbageGetValue "F2"
kF3 cabbageGetValue "F3"
kF3 cabbageGetValue "F4"
kL1 cabbageGetValue "L1"
kL2 cabbageGetValue "L2"
kL3 cabbageGetValue "L3"
kL4 cabbageGetValue "L4"
chnset kF2/kF1, "Ratio"
kListen0 cabbageGetValue "Listen0"
kListen3 cabbageGetValue "Listen3"
kListen4 cabbageGetValue "Listen4"
kSolo1 cabbageGetValue "Solo1"
kSolo2 cabbageGetValue "Solo2"
kF3 = abs(2*kF1 - kF2)
chnset kF3, "F3"
kF4 = abs(kF2 - kF1)
chnset kF4, "F4"
kPortTime = 0.03
kA0 portk (1 - kListen3) * (1 - kListen4) * (kListen0), kPortTime
kA3 portk kListen3, kPortTime
kA4 portk kListen4, kPortTime
a1 poscil ampdbfs(kL1), kF1
a2 poscil ampdbfs(kL2), kF2
aOAE poscil ampdbfs(kL3), kF3
aOAE2 poscil ampdbfs(kL4), kF4
if (kSolo1==1 || kSolo2==1) then
if kSolo1==1 then
a2 *= 1-kSolo1
elseif kSolo2==1 then
a1 *= 1-kSolo2
endif
endif
aMix = ((a1 + a2) * a(kA0)) + (aOAE * a(kA3)) + (aOAE2 * a(kA4))
outs aMix, aMix
if trigger:k(kListen0,0.5,0)==1 then
chnset k(0),"Listen3"
chnset k(0),"Listen4"
elseif trigger:k(kListen3,0.5,0)==1 then
chnset k(0),"Listen0"
chnset k(0),"Listen4"
elseif trigger:k(kListen4,0.5,0)==1 then
chnset k(0),"Listen0"
chnset k(0),"Listen3"
endif
if trigger:k(kSolo1,0.5,0)==1 then
chnset k(0),"Solo2"
elseif trigger:k(kSolo2,0.5,0)==1 then
chnset k(0),"Solo1"
endif
endin
i 1 0 [60*60*24*7]