@@ -64,13 +64,234 @@ class AudioSettingsViewController: SettingsViewController {
6464    override func  refresh( )  { 
6565
6666        super. refresh ( ) 
67+ 
68+         guard  let  config =  config else  {  return  } 
69+         
70+         //
71+         // Mixer
72+         //
73+ 
74+         // In
75+         audVol0. integerValue =  config. vol0
76+         audVol1. integerValue =  config. vol1
77+         audVol2. integerValue =  config. vol2
78+         audVol3. integerValue =  config. vol3
79+         audPan0. integerValue =  config. pan0
80+         audPan1. integerValue =  config. pan1
81+         audPan2. integerValue =  config. pan2
82+         audPan3. integerValue =  config. pan3
83+ 
84+         // Out
85+         audVolL. integerValue =  config. volL
86+         audVolR. integerValue =  config. volR
87+ 
88+         // Drives
89+         audStepVolume. integerValue =  config. stepVolume
90+         audPollVolume. integerValue =  config. pollVolume
91+         audInsertVolume. integerValue =  config. insertVolume
92+         audEjectVolume. integerValue =  config. ejectVolume
93+         audDf0Pan. integerValue =  config. df0Pan
94+         audDf1Pan. integerValue =  config. df1Pan
95+         audDf2Pan. integerValue =  config. df2Pan
96+         audDf3Pan. integerValue =  config. df3Pan
97+         audHd0Pan. integerValue =  config. hd0Pan
98+         audHd1Pan. integerValue =  config. hd1Pan
99+         audHd2Pan. integerValue =  config. hd2Pan
100+         audHd3Pan. integerValue =  config. hd3Pan
101+ 
102+         // Audio filter
103+         audFilterType. selectItem ( withTag:  config. filterType) 
104+ 
105+         //
106+         // Sampler
107+         //
108+ 
109+         audSamplingMethod. selectItem ( withTag:  config. samplingMethod) 
110+         audASR. selectItem ( withTag:  config. asr) 
111+         audCapacity. integerValue =  config. audioBufferSize
112+         audCapacityText. stringValue =  " \( config. audioBufferSize)  samples " 
113+ 
114+         /*
115+         switch SamplingMethod(rawValue: Int32(config.samplingMethod)) {
116+         case .NONE:
117+             audSamplingMethodText.stringValue = "Instructs the sampler to select the most recent sample from the ring buffer. This minimizes latency but may introduce jitter when the sample rate fluctuates."
118+         case .NEAREST:
119+             audSamplingMethodText.stringValue = "Instructs the sampler to pick the sample closest to the target timestamp. It improves timing accuracy over the latest-sample method but may still have minor mismatches."
120+         case .LINEAR:
121+             audSamplingMethodText.stringValue = "Instructs the sampler to compute a value between two neighboring samples for smoother output. Increases computation slightly but reduces artifacts and improves fidelity."
122+         default:
123+             break
124+         }
125+ 
126+         switch (config.asr) {
127+         case 0:
128+             audASRText.stringValue = "Audio samples are synthesized at a constant sampling rate, ignoring drift between emulated and real-time playback rates. This may cause buffer underflows and overflows over time, leading to audio stutter or glitches."
129+         default:
130+             audASRText.stringValue = "ASR (Adaptive Sample Rate) dynamically adjusts the sampling rate to maintain audio sync. This prevents buffer underflows and overflows by adapting to slight drift between emulated and real-time playback rates."
131+        */
67132    } 
68133
69134    override func  preset( tag:  Int )  { 
70135
136+         guard  let  emu =  emu,  let  config =  config else  {  return  } 
137+ 
138+         emu. suspend ( ) 
139+ 
140+         // Revert to standard settings
141+         EmulatorProxy . defaults. removeAudioUserDefaults ( ) 
142+ 
143+         // Update the configuration
144+         config. applyAudioUserDefaults ( ) 
145+ 
146+         switch  tag { 
147+ 
148+         case  0 :  // Standard
149+             config. pan0 =  50 
150+             config. pan1 =  350 
151+             config. pan2 =  350 
152+             config. pan3 =  50 
153+ 
154+         case  1 :  // Stereo
155+             config. pan0 =  100 
156+             config. pan1 =  300 
157+             config. pan2 =  300 
158+             config. pan3 =  100 
159+ 
160+         case  2 :  // Mono
161+             config. pan0 =  0 
162+             config. pan1 =  0 
163+             config. pan2 =  0 
164+             config. pan3 =  0 
165+ 
166+         default : 
167+             fatalError ( ) 
168+         } 
169+ 
170+         emu. resume ( ) 
71171    } 
72172
73173    override func  save( )  { 
74174
175+         config? . saveAudioUserDefaults ( ) 
176+     } 
177+ 
178+     //
179+     // Action functions (Mixer)
180+     //
181+ 
182+     @IBAction   func  audVol0Action( _ sender:  NSSlider ! )  { 
183+ 
184+         config? . vol0 =  sender. integerValue
185+     } 
186+ 
187+     @IBAction   func  audVol1Action( _ sender:  NSSlider ! )  { 
188+ 
189+         config? . vol1 =  sender. integerValue
190+     } 
191+ 
192+     @IBAction   func  audVol2Action( _ sender:  NSSlider ! )  { 
193+ 
194+         config? . vol2 =  sender. integerValue
195+     } 
196+ 
197+     @IBAction   func  audVol3Action( _ sender:  NSSlider ! )  { 
198+ 
199+         config? . vol3 =  sender. integerValue
200+     } 
201+ 
202+     @IBAction   func  audPan0Action( _ sender:  NSSlider ! )  { 
203+ 
204+         config? . pan0 =  sender. integerValue
205+     } 
206+ 
207+     @IBAction   func  audPan1Action( _ sender:  NSSlider ! )  { 
208+ 
209+         config? . pan1 =  sender. integerValue
210+     } 
211+ 
212+     @IBAction   func  audPan2Action( _ sender:  NSSlider ! )  { 
213+ 
214+         config? . pan2 =  sender. integerValue
215+     } 
216+ 
217+     @IBAction   func  audPan3Action( _ sender:  NSSlider ! )  { 
218+ 
219+         config? . pan3 =  sender. integerValue
220+     } 
221+ 
222+     @IBAction   func  audVolLAction( _ sender:  NSSlider ! )  { 
223+ 
224+         config? . volL =  sender. integerValue
225+     } 
226+ 
227+     @IBAction   func  audVolRAction( _ sender:  NSSlider ! )  { 
228+ 
229+         config? . volR =  sender. integerValue
230+     } 
231+ 
232+     @IBAction   func  audDrivePanAction( _ sender:  NSSlider ! )  { 
233+ 
234+         switch  sender. tag { 
235+         case  0 :  config? . df0Pan =  sender. integerValue
236+         case  1 :  config? . df1Pan =  sender. integerValue
237+         case  2 :  config? . df2Pan =  sender. integerValue
238+         case  3 :  config? . df3Pan =  sender. integerValue
239+         default :  fatalError ( ) 
240+         } 
241+     } 
242+ 
243+     @IBAction   func  audHdPanAction( _ sender:  NSSlider ! )  { 
244+ 
245+         switch  sender. tag { 
246+         case  0 :  config? . hd0Pan =  sender. integerValue
247+         case  1 :  config? . hd1Pan =  sender. integerValue
248+         case  2 :  config? . hd2Pan =  sender. integerValue
249+         case  3 :  config? . hd3Pan =  sender. integerValue
250+         default :  fatalError ( ) 
251+         } 
252+     } 
253+ 
254+     @IBAction   func  audStepVolumeAction( _ sender:  NSSlider ! )  { 
255+ 
256+         config? . stepVolume =  sender. integerValue
257+     } 
258+ 
259+     @IBAction   func  audPollVolumeAction( _ sender:  NSSlider ! )  { 
260+ 
261+         config? . pollVolume =  sender. integerValue
262+     } 
263+ 
264+     @IBAction   func  audInsertVolumeAction( _ sender:  NSSlider ! )  { 
265+ 
266+         config? . insertVolume =  sender. integerValue
267+     } 
268+ 
269+     @IBAction   func  audEjectVolumeAction( _ sender:  NSSlider ! )  { 
270+ 
271+         config? . ejectVolume =  sender. integerValue
272+     } 
273+ 
274+     @IBAction   func  audFilterTypeAction( _ sender:  NSPopUpButton ! )  { 
275+ 
276+         config? . filterType =  sender. selectedTag ( ) 
277+     } 
278+ 
279+     //
280+     // Action functions (Sampler)
281+     //
282+ 
283+     @IBAction   func  audSamplingMethodAction( _ sender:  NSPopUpButton ! )  { 
284+ 
285+         config? . samplingMethod =  sender. selectedTag ( ) 
286+     } 
287+ 
288+     @IBAction   func  audASRAction( _ sender:  NSPopUpButton ! )  { 
289+ 
290+         config? . asr =  sender. selectedTag ( ) 
291+     } 
292+ 
293+     @IBAction   func  audCapacityAction( _ sender:  NSSlider ! )  { 
294+ 
295+         config? . audioBufferSize =  sender. integerValue
75296    } 
76297} 
0 commit comments