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

如何用UDUNITS-2语法在R的units包中定义梅尔心理声学单位?

在R的units包中定义梅尔(Mel)单位及跨语言参考方案

R语言(units包)实现

虽然units包的单位解析依赖底层C实现,但可以通过注册自定义双向转换函数来添加梅尔单位:

  1. 先定义赫兹与梅尔的双向转换逻辑:

    • 梅尔转赫兹使用公式逆运算:f = 700*(exp(M/1127)-1)
    • 赫兹转梅尔使用给定公式:M = 1127*ln(1 + f/700)
  2. 注册新单位并测试转换:

library(units)

# 梅尔转赫兹的逆转换函数
hz_from_mel <- function(m) {
  700 * (exp(m / 1127) - 1)
}

# 赫兹转梅尔的转换函数
mel_from_hz <- function(f) {
  1127 * log(1 + f / 700)
}

# 注册梅尔单位,关联赫兹作为基准单位
install_unit("mel", def = "Hz",
             convert = list(
               Hz = mel_from_hz,
               mel = hz_from_mel
             ))

# 正向转换测试:1000Hz转梅尔
freq_hz <- set_units(1000, Hz)
freq_mel <- freq_hz %>% set_units(mel)
print(freq_mel)

# 反向转换测试:梅尔转回赫兹
freq_hz_back <- freq_mel %>% set_units(Hz)
print(freq_hz_back)

Python(Pint库)参考方案

Pint是Python中类似units的单位处理库,支持自定义非线性单位转换:

from pint import UnitRegistry
import math

ureg = UnitRegistry()

# 注册梅尔为频率单位
ureg.define('mel = [frequency]')

# 添加赫兹与梅尔的双向转换规则
ureg.add_transformation(ureg.hertz, ureg.mel, lambda f: 1127 * math.log(1 + f / 700))
ureg.add_transformation(ureg.mel, ureg.hertz, lambda m: 700 * (math.exp(m / 1127) - 1))

# 测试转换
freq_hz = 1000 * ureg.hertz
freq_mel = freq_hz.to('mel')
print(freq_mel)

freq_hz_back = freq_mel.to('hertz')
print(freq_hz_back)

C语言参考实现

如果需要直接在C中实现转换逻辑(无需单位库),可以封装转换函数:

#include <math.h>
#include <stdio.h>

// 赫兹转梅尔
double hz_to_mel(double f) {
    return 1127 * log(1 + f / 700.0);
}

// 梅尔转赫兹
double mel_to_hz(double m) {
    return 700.0 * (exp(m / 1127.0) - 1);
}

// 示例测试
int main() {
    double input_hz = 1000.0;
    double mel_val = hz_to_mel(input_hz);
    printf("%.2f Hz = %.2f Mel\n", input_hz, mel_val);
    
    double hz_val = mel_to_hz(mel_val);
    printf("%.2f Mel = %.2f Hz\n", mel_val, hz_val);
    return 0;
}

内容的提问来源于stack exchange,提问作者Fredrik Nylén

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:36:14