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 ;
openfirmware@openfirmware.info