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

如何通过AudioKit微音调重映射MIDI音符至自定义频率?附报错代码

在DunneAudioKit中实现MIDI音符到自定义频率的重映射

问题原因

你原代码的语法错误源于直接在类的属性定义区域调用方法——Swift不允许在这个位置执行TuningTableBase.setFrequency这类方法调用,必须将操作放在初始化方法或其他类方法中。

实现方案

无需修改核心播放代码,通过Microtonality框架的TuningTableBase实现自定义频率映射,步骤如下:

  • 初始化调律表实例
  • 定义一个八度内的12个自定义频率
  • 映射基础八度的MIDI音符与频率
  • 扩展映射到全MIDI范围的高低八度(倍频/分频)
  • 将调律表绑定到Synth乐器

完整可运行代码

import AudioKit
import Microtonality

class DunneSynthConductor: ObservableObject, HasAudioEngine {
    let engine = AudioEngine()
    var instrument = Synth()
    var tuningTable = TuningTableBase()

    init() {
        // 替换成你的12个自定义八度频率
        let customOctaveFrequencies: [Double] = [260.0, 278.0, 295.0, 312.0, 330.0, 350.0, 370.0, 395.0, 418.0, 442.0, 468.0, 495.0]
        
        // 选择基础MIDI音符(比如60对应C4,作为八度起始点)
        let baseMIDINote = 60
        
        // 映射基础八度的12个音符
        for (index, frequency) in customOctaveFrequencies.enumerated() {
            let midiNote = baseMIDINote + index
            tuningTable.setFrequency(frequency, at: midiNote)
        }
        
        // 扩展映射到全MIDI范围(0-127)的高低八度
        for octaveOffset in -5...5 {
            let octaveMultiplier = pow(2.0, Double(octaveOffset))
            for (index, baseFreq) in customOctaveFrequencies.enumerated() {
                let midiNote = baseMIDINote + index + (octaveOffset * 12)
                guard midiNote >= 0, midiNote <= 127 else { continue }
                tuningTable.setFrequency(baseFreq * octaveMultiplier, at: midiNote)
            }
        }
        
        // 将自定义调律表绑定到Synth
        instrument.tuningTable = tuningTable
        engine.output = instrument
    }
}

关键说明

  • 八度逻辑:通过pow(2.0, octaveOffset)计算倍频/分频,保证高八度频率是基础八度的2倍,低八度是1/2倍,符合常规八度音程关系
  • 全范围覆盖:循环处理-5到5的八度偏移,完全覆盖MIDI 0-127的所有音符
  • 无侵入式修改:仅通过绑定调律表实现频率重映射,无需改动Synth的核心播放逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:56:14