You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否创建5个可同时运行的振荡器数组并独立控制各振荡器的频率与振幅?

实现5个独立控制的音频振荡器(AudioKit + SwiftUI)

可以实现5个同时工作且独立控制的振荡器,核心是用数组存储多个振荡器实例,再通过Mixer将所有音频信号混合后输出。下面是适配Xcode项目的完整实现方案:

修改音频生成器类

首先重构ToneGenerator,用数组管理多个振荡器,并用混音器合并信号:

import AudioKit
import AVFoundation

class ToneGenerator {
    let engine = AudioEngine()
    let mixer = Mixer()
    // 存储5个振荡器的数组
    var oscillators: [PlaygroundOscillator] = []
    
    init() {
        // 初始化5个振荡器,添加到混音器
        for _ in 0..<5 {
            let osc = PlaygroundOscillator()
            osc.amplitude = 0 // 默认静音
            oscillators.append(osc)
            mixer.addInput(osc)
        }
        
        // 将混音器设为引擎输出
        engine.output = mixer
        
        // 启动音频引擎(添加错误处理避免崩溃)
        do {
            try engine.start()
        } catch {
            print("音频引擎启动失败: \(error.localizedDescription)")
        }
    }
    
    // 控制指定索引的振荡器启停
    func toggleOscillator(at index: Int, isOn: Bool) {
        guard index < oscillators.count else { return }
        if isOn {
            oscillators[index].start()
        } else {
            oscillators[index].stop()
        }
    }
    
    // 设置指定索引振荡器的频率
    func setFrequency(for index: Int, value: Float) {
        guard index < oscillators.count else { return }
        oscillators[index].frequency = value
    }
    
    // 设置指定索引振荡器的振幅
    func setAmplitude(for index: Int, value: Float) {
        guard index < oscillators.count else { return }
        oscillators[index].amplitude = value
    }
}

构建SwiftUI交互界面

在ContentView中添加独立控件,分别控制每个振荡器的开关、频率和振幅:

import SwiftUI

struct ContentView: View {
    let toneGenerator = ToneGenerator()
    
    // 为每个振荡器定义独立的状态
    @State private var oscillatorStates: [Bool] = Array(repeating: false, count: 5)
    @State private var frequencies: [Float] = [200, 300, 400, 500, 600]
    @State private var amplitudes: [Float] = Array(repeating: 0.5, count: 5)
    
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                ForEach(0..<5, id: \.self) { index in
                    VStack(spacing: 10) {
                        Text("振荡器 \(index + 1)")
                            .font(.headline)
                        
                        // 开关按钮
                        Button(action: {
                            oscillatorStates[index].toggle()
                            toneGenerator.toggleOscillator(at: index, isOn: oscillatorStates[index])
                        }) {
                            Text(oscillatorStates[index] ? "停止" : "播放")
                                .frame(width: 80, height: 40)
                                .background(oscillatorStates[index] ? Color.red : Color.green)
                                .foregroundColor(.white)
                                .cornerRadius(8)
                        }
                        
                        // 频率滑块
                        HStack {
                            Text("频率: \(Int(frequencies[index])) Hz")
                            Slider(value: $frequencies[index], in: 50...1000) { _ in
                                toneGenerator.setFrequency(for: index, value: frequencies[index])
                            }
                        }
                        
                        // 振幅滑块
                        HStack {
                            Text("音量: \(String(format: "%.2f", amplitudes[index]))")
                            Slider(value: $amplitudes[index], in: 0...1) { _ in
                                toneGenerator.setAmplitude(for: index, value: amplitudes[index])
                            }
                        }
                    }
                    .padding()
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(10)
                }
            }
            .padding()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键说明

  • 数组管理振荡器:用[PlaygroundOscillator]存储5个实例,通过索引快速定位操作目标
  • 混音器合并信号:所有振荡器的输出都接入Mixer,再统一输出到音频引擎,避免多个直接输出冲突
  • 独立状态控制:每个振荡器对应独立的开关、频率、振幅状态变量,确保操作互不干扰
  • 错误处理优化:替换原代码的try!为do-catch,避免音频引擎启动失败导致崩溃

内容的提问来源于stack exchange,提问作者Peter_22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:40:37