Author: wmb
Date: 2010-01-22 06:43:23 +0100 (Fri, 22 Jan 2010)
New Revision: 1682
Added:
dev/hdaudio/olpc-ports.fth
Modified:
dev/hdaudio/conexant.fth
dev/hdaudio/noiseburst.fth
dev/hdaudio/test.fth
Log:
Integrated noise-correlation-based automatic seltest into OLPC XO-1.5 audio driver.
Modified: dev/hdaudio/conexant.fth
===================================================================
--- dev/hdaudio/conexant.fth 2010-01-21 23:02:56 UTC (rev 1681)
+++ dev/hdaudio/conexant.fth 2010-01-22 05:43:23 UTC (rev 1682)
@@ -29,12 +29,10 @@
: enable-hp-input ( -- ) h# 70721 cmd ;
: disable-hp-input ( -- ) h# 70700 cmd ;
+fload ${BP}/dev/hdaudio/olpc-ports.fth
+
: cx2058x-enable-recording ( -- )
- portb pin-sense? if
- mux 0 set-connection portb enable-hp-input
- else
- mux 1 set-connection portc enable-hp-input
- then
+ set-recording-port
;
: cx2058x-disable-recording ( -- )
@@ -43,11 +41,7 @@
;
: cx2058x-enable-playback ( -- )
- porta pin-sense? if \ headphones attached
- portg power-off \ turn off speaker
- else \ no headphones
- portg power-on \ turn on speaker
- then
+ set-playback-port
dac1 h# 70640 cmd \ 706sc - stream 4, channel 0
h# 20000 stream-format or cmd
;
Modified: dev/hdaudio/noiseburst.fth
===================================================================
--- dev/hdaudio/noiseburst.fth 2010-01-21 23:02:56 UTC (rev 1681)
+++ dev/hdaudio/noiseburst.fth 2010-01-22 05:43:23 UTC (rev 1682)
@@ -1,6 +1,8 @@
-.( cross-covariance audio test) cr
-select /audio
+\ See license at end of file
+purpose: Cross-covariance audio selftest
+support-package: audio-test
+
code mono-covar ( adr1 adr2 #samples -- d.sum )
cx pop
@@ -296,18 +298,11 @@
>r wa1+ dup r> 2/ 2/ stereo-covar
;
-h# 40000 value /pb \ Stereo - 10000 is okay for fixter, 40000 is better for case,
+h# 40000 value /pb \ Stereo - 10000 is okay for fixture, 40000 is better for case,
: pb load-base ;
h# 21000 value /rb \ Mono (stereo for loopback) - 8100 for fixture, 21000 for case,
: rb load-base 1meg + ;
-: random-signal ( -- )
- pb /pb bounds do random-byte i c! loop
- pb /pb -stereo-wmean
- pb wa1+ /pb -stereo-wmean
- pb /pb lose-6db
-;
-
: d.. ( -- ) <# # # # # ascii . hold # # # # ascii . hold #s #> type space ;
: find-max-mono ( -- )
pb rb /pb 2 / h# 100 - d# 160 d# 120 mono-covar-max .d max-covar d..
@@ -338,51 +333,56 @@
.covar#
;
+0 value debug?
+: >ratio ( sum1 sum2 -- ratio*10 )
+ debug? if over .d dup .d ." : " then
+ 1 max d# 10 swap */
+ debug? if dup .d cr then
+;
\ Reasonable threshold is d# 25
-: fixture-ratio-left ( -- )
+: fixture-ratio-left ( -- error? )
left-range d# 240 d# 140 sm-covar-abs-sum nip ( sum1 )
left-range d# 400 d# 300 sm-covar-abs-sum nip ( sum1 sum2 )
- d# 10 swap */
- .d
+ >ratio
+ d# 25 <
;
-: fixture-ratio-right ( -- )
+: fixture-ratio-right ( -- error? )
right-range d# 240 d# 140 sm-covar-abs-sum nip ( sum1 )
right-range d# 400 d# 300 sm-covar-abs-sum nip ( sum1 sum2 )
- d# 10 swap */
- .d
+ >ratio
+ d# 25 <
;
\ This compares the total energy within the impulse response band to the
\ total energy in a similar-length band
-: case-ratio-left ( -- ratio )
+: case-ratio-left ( -- error? )
left-range d# 200 d# 140 sm-covar-abs-sum nip ( sum1.high )
left-range d# 540 d# 400 sm-covar-abs-sum nip ( sum1.high sum2.high )
- d# 10 swap */
- .d
+ >ratio
+ d# 30 <
;
-: case-ratio-right ( -- ratio )
+: case-ratio-right ( -- error? )
right-range d# 330 d# 140 sm-covar-abs-sum nip ( sum1.high )
right-range d# 590 d# 400 sm-covar-abs-sum nip ( sum1.high sum2.high )
- d# 10 swap */
- .d
+ >ratio
+ d# 15 <
;
\ This compares the total energy within the impulse response band to the
\ total energy in a similar-length band
-: loopback-ratio-left ( -- )
+: loopback-ratio-left ( -- error? )
left-stereo-range d# 148 d# 128 ss-covar-abs-sum nip ( sum1.high )
left-stereo-range d# 220 d# 200 ss-covar-abs-sum nip ( sum1.high sum2.high )
- d# 10 swap */
- .d
+ >ratio
+ d# 70 <
;
-: loopback-ratio-right ( -- )
+: loopback-ratio-right ( -- error? )
right-stereo-range d# 148 d# 128 ss-covar-abs-sum nip ( sum1.high )
right-stereo-range d# 220 d# 200 ss-covar-abs-sum nip ( sum1.high sum2.high )
- d# 10 swap */
- .d
+ >ratio
+ d# 70 <
;
-
d# 1024 /w* buffer: impulse-response
: calc-sm-impulse ( offset -- ) \ offset is 0 for left or 2 for right
@@ -402,14 +402,34 @@
drop
;
d# -23 value test-volume \ d# -23 for test fixture, d# -9 for in-case
-defer rx-channels ' mono is rx-channels \ set to stereo for loopback
defer analyze-left
defer analyze-right
defer fix-dc
+
+: prepare-signal ( -- out-adr, len in-adr,len )
+ pb /pb bounds do random-byte i c! loop
+ pb /pb -stereo-wmean
+ pb wa1+ /pb -stereo-wmean
+ pb /pb lose-6db
+ pb /pb rb /rb
+ disable-interrupts
+;
+: analyze-signal ( -- error? )
+ enable-interrupts
+ rb /rb fix-dc
+ false ( error? )
+ analyze-left if ( error? )
+ ." Left channel failure" cr
+ 1+
+ then
+
+ analyze-right if
+ ." Right channel failure" cr
+ 2+
+ then
+;
+
: setup-fixture ( -- )
- xxx - this needs to use the internal speakers and mic even though the loopback cable is attached
- ['] mono is rx-channels
- d# -23 is test-volume
h# 20000 to /pb \ Medium burst
/pb 2/ h# 1000 + to /rb \ Mono reception (internal mic)
\ ['] fixture-analyze-left to analyze-left
@@ -419,9 +439,7 @@
['] -mono-wmean to fix-dc
;
: setup-case ( -- )
- xxx - this needs to use the internal speakers and mic even though the loopback cable is attached
- ['] mono is rx-channels
- d# -9 is test-volume
+\ xxx - this needs to use the internal speakers and mic even though the loopback cable is attached
h# 40000 to /pb \ Long burst for better S/N on far away speaker
/pb 2/ h# 1000 + to /rb \ Mono reception (internal mic)
['] case-ratio-left to analyze-left
@@ -429,28 +447,15 @@
['] -mono-wmean to fix-dc
;
: setup-loopback ( -- )
- ['] stereo is rx-channels
- d# -33 is test-volume
h# 10000 to /pb \ Short burst
/pb h# 1000 + to /rb \ Stereo reception
['] loopback-ratio-left to analyze-left
['] loopback-ratio-right to analyze-right
['] -stereo-wmean to fix-dc
;
-: doit ( -- )
- open-in 48kHz 16bit rx-channels with-adc d# 73 input-gain
- \ -23 prevents obvious visible clipping
- open-out 48kHz 16bit stereo test-volume set-volume
- random-signal
- lock[ \ Prevent timing jitter due to interrupts
- pb /pb rb /rb out-in
- ]unlock
- rb /rb fix-dc
-\ ." Mono " find-max-mono cr
-\ ." Left " find-max-left cr
-\ ." Right " find-max-right cr
- analyze-left analyze-right
-;
+: open ( -- okay? ) true ;
+: close ( -- ) ;
+end-support-package
0 [if]
: make-tone2 ( freq -- )
@@ -483,4 +488,27 @@
rb waveform
;
[then]
-.( loaded) cr
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2010 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Added: dev/hdaudio/olpc-ports.fth
===================================================================
--- dev/hdaudio/olpc-ports.fth (rev 0)
+++ dev/hdaudio/olpc-ports.fth 2010-01-22 05:43:23 UTC (rev 1682)
@@ -0,0 +1,59 @@
+\ See license at end of file
+purpose: Conexant CX2058x CODEC driver words reflecting OLPC port usage
+
+: headphone-jack ( -- ) porta ;
+: external-mic ( -- ) portb ;
+: internal-mic ( -- ) portc ;
+: dc-input ( -- ) portf ;
+: internal-speakers ( -- ) portg ;
+: speakers-on ( -- ) internal-speakers power-on ;
+: speakers-off ( -- ) internal-speakers power-off ;
+
+\ Set this to use the speakers even if the headphone jack is plugged
+false value force-speakers?
+: set-playback-port ( -- )
+ headphone-jack pin-sense? force-speakers? 0= and if \ headphones attached
+ speakers-off
+ else \ no headphones
+ speakers-on
+ then
+;
+: select-internal-mic ( -- )
+ mux 1 set-connection internal-mic enable-hp-input
+;
+: select-external-mic ( -- )
+ mux 0 set-connection external-mic enable-hp-input
+;
+\ Set this to use the internal mic even if an external mic is plugged in
+false value force-internal-mic?
+: set-recording-port ( -- )
+ external-mic pin-sense? force-internal-mic? 0= and if
+ select-external-mic
+ else
+ select-internal-mic
+ then
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2010 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Modified: dev/hdaudio/test.fth
===================================================================
--- dev/hdaudio/test.fth 2010-01-21 23:02:56 UTC (rev 1681)
+++ dev/hdaudio/test.fth 2010-01-22 05:43:23 UTC (rev 1682)
@@ -13,27 +13,31 @@
key h# 1b = if ." Aborting" abort then
then
;
-: speaker-test ( -- )
- h# 19 to node
- 2 to #channels
- pin-sense? if
+: connect-headphones ( -- )
+ headphone-jack pin-sense? 0= if
+ ." Connect headphones to continue.. "
+ begin ?key-abort pin-sense? until cr
+ then
+;
+: disconnect-headphones ( -- )
+ headphone-jack pin-sense? if
." Disconnect headphones to continue.. "
begin ?key-abort pin-sense? 0= until cr
then
+;
+: speaker-test ( -- )
+ disconnect-headphones
+ 2 to #channels
." Playing left to right sweep "
make-sweep 0 set-volume play cr
;
: headphones-test ( -- )
- h# 19 to node
2 to #channels
- pin-sense? 0= if
- ." Connect headphones to continue.. "
- begin ?key-abort pin-sense? until cr
- then
- h# 1f to node power-off \ turn off speaker
+ connect-headphones
+ speakers-off \ turn off speaker
make-sweep -9 set-volume play
- h# 1f to node power-on \ turn speaker back on
+ speakers-on \ turn speaker back on
;
: louder-mic-test ( -- )
@@ -43,30 +47,85 @@
d# 0 set-volume play
;
-: builtin-mic-test ( -- )
- h# 1a to node
- pin-sense? if
+: connect-mic
+ external-mic pin-sense? 0= if
+ ." Connect microphone to continue.. "
+ begin ?key-abort pin-sense? until cr
+ then
+;
+: disconnect-mic ( -- )
+ external-mic pin-sense? if
." Disconnect microphone to continue.. "
begin ?key-abort pin-sense? 0= until cr
then
+;
+
+: builtin-mic-test ( -- )
+ disconnect-mic
." Press a key to test recording / playback on the built-in microphone.. "
key drop cr
louder-mic-test
;
: external-mic-test ( -- )
- h# 1a to node
- pin-sense? 0= if
- ." Connect microphone to continue.. "
- begin ?key-abort pin-sense? until cr
- then
+ connect-mic
." Press a key to test recording / playback on the external microphone.. "
key drop cr
mic-test
;
+0 value analyzer-ih
+: $call-analyzer ( ? name$ -- ? ) analyzer-ih $call-method ;
+: open-analyzer ( -- )
+ analyzer-ih 0= if
+ " " " audio-test" $open-package to analyzer-ih
+ then
+;
+: close-analyzer ( -- )
+ analyzer-ih if
+ analyzer-ih close-package
+ 0 to analyzer-ih
+ then
+;
+: test-common ( setup$ -- error? )
+ $call-analyzer ( )
+ " prepare-signal" $call-analyzer ( pb /pb rb /rb )
+ \ First time lets the input channel settle
+ 2over 2over out-in ( pb /pb rb /rb )
+ out-in ( )
+ " analyze-signal" $call-analyzer ( okay? )
+;
+: input-common-settings ( -- )
+ open-in 48kHz 16bit with-adc d# 73 input-gain
+;
+: output-common-settings ( -- )
+ open-out 48kHz 16bit stereo
+;
+: test-with-case ( -- )
+ " setup-case" $call-analyzer
+\ xxx - this needs to use the internal speakers and mic even though the loopback cable is attached
+ true to force-speakers? true to force-internal-mic?
+ input-common-settings mono
+ output-common-settings d# -9 set-volume
+ " setup-case" test-common
+ false to force-speakers? false to force-internal-mic?
+;
+: test-with-fixture ( -- error? )
+ true to force-speakers? true to force-internal-mic?
+ input-common-settings mono
+ output-common-settings d# -23 set-volume \ -23 prevents obvious visible clipping
+ " setup-fixture" test-common
+ false to force-speakers? false to force-internal-mic?
+
+;
+: test-with-loopback ( -- error? )
+ input-common-settings stereo
+ output-common-settings d# -33 set-volume \ -23 prevents obvious visible clipping
+ " setup-loopback" test-common
+;
+
0 value saved-volume
-: interactive-test ( -- error? )
+: (interactive-test) ( -- error? )
alloc-buffer
headphones-test
external-mic-test
@@ -75,16 +134,50 @@
dealloc-buffer
" confirm-selftest?" eval
;
-: selftest ( -- )
+: interactive-test ( -- )
+ " playback-volume" evaluate to saved-volume
+ 0 " to playback-volume" evaluate
+ ['] (interactive-test) catch if true then
+ saved-volume " to playback-volume" evaluate
+;
+: loopback-connected? ( -- flag )
+ headphone-jack pin-sense? external-mic pin-sense? and
+;
+: loopback-disconnected? ( -- flag )
+ headphone-jack pin-sense? 0= external-mic pin-sense? 0= and
+;
+: connect-loopback ( -- )
+ loopback-connected? 0= if
+ ." Connect loopback cable to continue.. "
+ begin ?key-abort loopback-connected? until cr
+ then
+;
+: disconnect-loopback ( -- )
+ loopback-disconnected? 0= if
+ ." Disconnect loopback cable to continue.. "
+ begin ?key-abort loopback-disconnected? until cr
+ then
+;
+\ Returns failure by throwing
+: automatic-test ( -- )
+ " smt-test?" evaluate if
+ test-with-fixture throw
+ else
+ test-with-case throw
+ then
+ connect-loopback
+ test-with-loopback throw
+ disconnect-loopback
+;
+: selftest ( -- error? )
diagnostic-mode? if
open 0= if ." Failed to open /audio" cr true exit then
- " playback-volume" evaluate to saved-volume
- 0 " to playback-volume" evaluate
- ['] interactive-test catch if true then
- saved-volume " to playback-volume" evaluate
- close
+ open-analyzer
+ ['] automatic-test catch ( error? )
+ close-analyzer ( error? )
+ close ( error? )
else
- selftest
+ selftest ( error? )
then
;