@@ -93,7 +93,6 @@ const paramTypes = {
93
93
logFdcCommands : ParamTypes . BOOL ,
94
94
logFdcStateChanges : ParamTypes . BOOL ,
95
95
coProcessor : ParamTypes . BOOL ,
96
- useAnalogueAudio : ParamTypes . BOOL ,
97
96
98
97
// Numeric parameters
99
98
speed : ParamTypes . INT ,
@@ -242,6 +241,16 @@ const config = new Config(function (changed) {
242
241
emulationConfig . keyLayout = changed . keyLayout ;
243
242
keyboard . setKeyLayout ( changed . keyLayout ) ;
244
243
}
244
+ // Restore gamepad as source for the old channels
245
+ for ( let oldChannel = 0 ; oldChannel < 3 ; ++ oldChannel )
246
+ processor . adconverter . setChannelSource ( oldChannel , gamepadSource ) ;
247
+ if ( changed . microphoneChannel !== undefined ) {
248
+ const channel = changed . microphoneChannel ;
249
+ console . log ( `Moving microphone to channel ${ channel } ` ) ;
250
+ processor . adconverter . setChannelSource ( channel , microphoneInput ) ;
251
+ setupMicrophone ( ) . then ( ( ) => { } ) ;
252
+ }
253
+ updateUrl ( ) ;
245
254
} ) ;
246
255
247
256
// Perform mapping of legacy models to the new format
@@ -253,21 +262,7 @@ config.set65c02(parsedQuery.coProcessor);
253
262
config . setEconet ( parsedQuery . hasEconet ) ;
254
263
config . setMusic5000 ( parsedQuery . hasMusic5000 ) ;
255
264
config . setTeletext ( parsedQuery . hasTeletextAdaptor ) ;
256
-
257
- const microphoneSetupNeeded = queryString . includes ( "useAnalogueAudio" ) || queryString . includes ( "microphoneChannel" ) ;
258
- let microphoneChannelFromUrl = undefined ;
259
-
260
- if ( microphoneSetupNeeded ) {
261
- console . log ( "Microphone: URL parameters detected for microphone" ) ;
262
- // Save this to apply later
263
- if ( parsedQuery . microphoneChannel !== undefined ) {
264
- console . log ( "Microphone: URL parameter microphoneChannel =" , parsedQuery . microphoneChannel ) ;
265
- microphoneChannelFromUrl = parsedQuery . microphoneChannel ;
266
- }
267
-
268
- // We need to delay initialisation until after the processor and microphoneInput are created
269
- console . log ( "Microphone: Will initialise after processor is created" ) ;
270
- }
265
+ config . setMicrophoneChannel ( parsedQuery . microphoneChannel ) ;
271
266
272
267
model = config . model ;
273
268
@@ -526,76 +521,60 @@ microphoneInput.setErrorCallback((message) => {
526
521
showError ( "accessing microphone" , message ) ;
527
522
} ) ;
528
523
529
- // Now that the microphoneInput is created, we can apply the settings from URL parameters
530
- if ( microphoneSetupNeeded ) {
531
- console . log ( "Microphone: Initialising from URL parameters" ) ;
532
-
533
- // First, update the UI
534
- $ ( "#useAnalogueAudio" ) . prop ( "checked" , true ) ;
535
- $ ( "#analogueAudioSettings" ) . show ( ) ;
524
+ async function setupMicrophone ( ) {
525
+ const $micPermissionStatus = $ ( "#micPermissionStatus" ) ;
526
+ $micPermissionStatus . text ( "Requesting microphone access..." ) ;
527
+
528
+ // Try to initialise the microphone
529
+ const success = await microphoneInput . initialise ( ) ;
530
+ if ( success ) {
531
+ console . log ( "Microphone: Successfully initialised from URL parameters" ) ;
532
+ // Set microphone as source for its channel
533
+ console . log ( `Setting microphone as source for channel ${ parsedQuery . microphoneChannel } ` ) ;
534
+ processor . adconverter . setChannelSource ( parsedQuery . microphoneChannel , microphoneInput ) ;
535
+ $micPermissionStatus . text ( "Microphone connected successfully" ) ;
536
+
537
+ // Ensure audio context is running
538
+ if ( microphoneInput . audioContext ) {
539
+ console . log (
540
+ "Microphone: Ensuring audio context is running, current state:" ,
541
+ microphoneInput . audioContext . state ,
542
+ ) ;
543
+ try {
544
+ await microphoneInput . audioContext . resume ( ) ;
545
+ console . log ( "Microphone: Audio context resumed, new state:" , microphoneInput . audioContext . state ) ;
546
+ } catch ( err ) {
547
+ console . error ( "Microphone: Error resuming audio context:" , err ) ;
548
+ }
549
+ }
536
550
537
- // Apply channel setting if provided
538
- if ( microphoneChannelFromUrl !== undefined ) {
539
- console . log ( "Microphone: Setting channel from URL parameter to" , microphoneChannelFromUrl ) ;
540
- $ ( ".mic-channel-text" ) . text ( `Channel ${ microphoneChannelFromUrl } ` ) ;
551
+ // Try starting audio context from user gesture
552
+ const tryAgain = ( ) => {
553
+ if ( microphoneInput . audioContext && microphoneInput . audioContext . state !== "running" ) {
554
+ console . log ( "Microphone: Auto-starting audio context from click" ) ;
555
+ microphoneInput . audioContext . resume ( ) ;
556
+ }
557
+ document . removeEventListener ( "click" , tryAgain ) ;
558
+ } ;
559
+ document . addEventListener ( "click" , tryAgain ) ;
560
+ } else {
561
+ console . error ( "Microphone: Failed to initialise from URL parameters:" , microphoneInput . getErrorMessage ( ) ) ;
562
+ $micPermissionStatus . text ( `Error: ${ microphoneInput . getErrorMessage ( ) || "Unknown error" } ` ) ;
563
+ config . setMicrophoneChannel ( undefined ) ;
564
+ // Update URL to remove the parameter
565
+ delete parsedQuery . microphoneChannel ;
566
+ updateUrl ( ) ;
541
567
}
568
+ }
569
+
570
+ if ( parsedQuery . microphoneChannel !== undefined ) {
571
+ console . log ( "Microphone: Initialising from URL parameters" ) ;
542
572
543
573
// We need to use setTimeout to make sure this runs after the page has loaded
544
574
// This is needed because some browsers require user interaction for audio context
545
575
setTimeout ( async ( ) => {
546
576
console . log ( "Microphone: Delayed initialisation starting" ) ;
547
- $ ( "#micPermissionStatus" ) . text ( "Requesting microphone access..." ) ;
548
-
549
- // Try to initialise the microphone
550
- const success = await microphoneInput . initialise ( ) ;
551
- if ( success ) {
552
- console . log ( "Microphone: Successfully initialised from URL parameters" ) ;
553
- // Set microphone as source for its channel
554
- console . log ( `Setting microphone as source for channel ${ microphoneChannelFromUrl } ` ) ;
555
- processor . adconverter . setChannelSource ( microphoneChannelFromUrl , microphoneInput ) ;
556
- $ ( "#micPermissionStatus" ) . text ( "Microphone connected successfully" ) ;
557
-
558
- // Ensure audio context is running
559
- if ( microphoneInput . audioContext ) {
560
- console . log (
561
- "Microphone: Ensuring audio context is running, current state:" ,
562
- microphoneInput . audioContext . state ,
563
- ) ;
564
- try {
565
- await microphoneInput . audioContext . resume ( ) ;
566
- console . log ( "Microphone: Audio context resumed, new state:" , microphoneInput . audioContext . state ) ;
567
- } catch ( err ) {
568
- console . error ( "Microphone: Error resuming audio context:" , err ) ;
569
- }
570
- }
571
-
572
- // Try starting audio context from user gesture
573
- const tryAgain = ( ) => {
574
- if ( microphoneInput . audioContext && microphoneInput . audioContext . state !== "running" ) {
575
- console . log ( "Microphone: Auto-starting audio context from click" ) ;
576
- microphoneInput . audioContext . resume ( ) ;
577
- }
578
- document . removeEventListener ( "click" , tryAgain ) ;
579
- } ;
580
- document . addEventListener ( "click" , tryAgain ) ;
581
-
582
- // Make sure URL parameter is reflected in the UI
583
- parsedQuery . useAnalogueAudio = true ;
584
- if ( microphoneChannelFromUrl !== undefined ) {
585
- parsedQuery . microphoneChannel = microphoneChannelFromUrl ;
586
- }
587
- updateUrl ( ) ;
588
- } else {
589
- console . error ( "Microphone: Failed to initialise from URL parameters:" , microphoneInput . getErrorMessage ( ) ) ;
590
- $ ( "#micPermissionStatus" ) . text ( `Error: ${ microphoneInput . getErrorMessage ( ) || "Unknown error" } ` ) ;
591
- // Uncheck the checkbox since initialisation failed
592
- $ ( "#useAnalogueAudio" ) . prop ( "checked" , false ) ;
593
- $ ( "#analogueAudioSettings" ) . hide ( ) ;
594
- // Update URL to remove the parameter
595
- parsedQuery . useAnalogueAudio = false ;
596
- delete parsedQuery . microphoneChannel ;
597
- updateUrl ( ) ;
598
- }
577
+ await setupMicrophone ( ) ;
599
578
} , 1000 ) ;
600
579
}
601
580
@@ -693,101 +672,6 @@ document.onkeydown = (evt) => {
693
672
document . onkeypress = ( evt ) => keyboard . keyPress ( evt ) ;
694
673
document . onkeyup = ( evt ) => keyboard . keyUp ( evt ) ;
695
674
696
- // Set up microphone UI handlers
697
- $ ( "#useAnalogueAudio" ) . on ( "change" , async function ( ) {
698
- const useAudio = $ ( this ) . prop ( "checked" ) ;
699
- console . log ( "Analogue audio checkbox changed:" , useAudio ) ;
700
- $ ( "#analogueAudioSettings" ) . toggle ( useAudio ) ;
701
-
702
- if ( useAudio ) {
703
- console . log ( "Initialising microphone input" ) ;
704
- $ ( "#micPermissionStatus" ) . text ( "Requesting microphone access..." ) ;
705
- const success = await microphoneInput . initialise ( ) ;
706
-
707
- if ( success ) {
708
- console . log ( "Adding microphone input source to ADC" ) ;
709
-
710
- // Set microphone as the source for its channel
711
- console . log ( `Setting microphone as source for channel ${ microphoneChannelFromUrl } ` ) ;
712
- processor . adconverter . setChannelSource ( microphoneChannelFromUrl , microphoneInput ) ;
713
- $ ( "#micPermissionStatus" ) . text ( "Microphone connected successfully" ) ;
714
- // Also resume audio context to ensure it's running
715
- if ( audioHandler . audioContext ) {
716
- console . log ( "Resuming audio context, current state:" , audioHandler . audioContext . state ) ;
717
- try {
718
- await audioHandler . audioContext . resume ( ) ;
719
- console . log ( "Audio context resumed, new state:" , audioHandler . audioContext . state ) ;
720
- } catch ( err ) {
721
- console . error ( "Error resuming audio context:" , err ) ;
722
- }
723
- } else {
724
- console . log ( "No audio context found in audioHandler" ) ;
725
- }
726
-
727
- // Also make sure the microphone's audio context is resumed
728
- if ( microphoneInput . audioContext ) {
729
- console . log ( "Resuming microphone audio context, current state:" , microphoneInput . audioContext . state ) ;
730
- try {
731
- await microphoneInput . audioContext . resume ( ) ;
732
- console . log ( "Microphone audio context resumed, new state:" , microphoneInput . audioContext . state ) ;
733
- } catch ( err ) {
734
- console . error ( "Error resuming microphone audio context:" , err ) ;
735
- }
736
- }
737
- } else {
738
- const errorMsg = microphoneInput . getErrorMessage ( ) || "Unknown error" ;
739
- console . error ( "Failed to initialise microphone:" , errorMsg ) ;
740
- $ ( "#micPermissionStatus" ) . text ( `Error: ${ errorMsg } ` ) ;
741
- $ ( this ) . prop ( "checked" , false ) ;
742
- $ ( "#analogueAudioSettings" ) . hide ( ) ;
743
- }
744
- } else {
745
- console . log ( "Removing microphone input source from ADC" ) ;
746
- // Restore gamepad as the source for the microphone channel
747
- console . log ( `Restoring gamepad as source for channel ${ microphoneChannelFromUrl } ` ) ;
748
- processor . adconverter . setChannelSource ( microphoneChannelFromUrl , gamepadSource ) ;
749
-
750
- $ ( "#micPermissionStatus" ) . text ( "" ) ;
751
- }
752
-
753
- // Update URL parameters
754
- parsedQuery . useAnalogueAudio = useAudio ;
755
- if ( useAudio ) {
756
- parsedQuery . microphoneChannel = microphoneChannelFromUrl ;
757
- console . log ( "Set URL parameter microphoneChannel =" , microphoneChannelFromUrl ) ;
758
- } else {
759
- delete parsedQuery . microphoneChannel ;
760
- console . log ( "Removed URL parameter microphoneChannel" ) ;
761
- }
762
- updateUrl ( ) ;
763
- console . log ( "URL updated with new parameters" ) ;
764
- } ) ;
765
-
766
- // Handle microphone channel selection
767
- $ ( ".mic-channel-option" ) . on ( "click" , function ( ) {
768
- const channel = parseInt ( $ ( this ) . data ( "channel" ) , 10 ) ;
769
- console . log ( `Microphone channel changed to ${ channel } ` ) ;
770
-
771
- // Set the channel in microphone input
772
- $ ( ".mic-channel-text" ) . text ( `Channel ${ channel } ` ) ;
773
-
774
- // Update channel assignment in ADC if microphone is enabled
775
- if ( $ ( "#useAnalogueAudio" ) . prop ( "checked" ) ) {
776
- console . log ( `Moving microphone to channel ${ channel } ` ) ;
777
-
778
- // Restore gamepad as source for the old channel
779
- for ( let oldChannel = 0 ; oldChannel < 3 ; ++ oldChannel )
780
- processor . adconverter . setChannelSource ( oldChannel , gamepadSource ) ;
781
-
782
- // Set microphone as source for the new channel
783
- processor . adconverter . setChannelSource ( channel , microphoneInput ) ;
784
-
785
- // Update URL parameters
786
- parsedQuery . microphoneChannel = channel ;
787
- updateUrl ( ) ;
788
- }
789
- } ) ;
790
-
791
675
function setDisc1Image ( name ) {
792
676
delete parsedQuery . disc ;
793
677
parsedQuery . disc1 = name ;
0 commit comments