我正在尝试使用此处给出的rt_lpc(实时LPC)实现进行离线LPC分析和综合。该程序中有一些功能可用于脱机LPC分析和综合程序。 rt_lpc代码主要用于作曲家等,这意味着它使用MIDI或声门脉冲输入。程序中有一些代码将音调值(从自相关获得)转换为bend值。该关系如下所示:

    pitch = (int)( Stk::sampleRate() / midi2pitch[ananya.data[1]] ) /
                            pow( 1.0653f, bend/64.0f*11.0f );
                    power *= ananya.data[2] / 64.0f;
bend = ge.data[1] / 128.0f + ge.data[2] - 64;


一些要点:
a。 ananyaMidiMsg类型的对象,似乎是即时填充的。
b。 ge也是MidiMsg类型的对象,它似乎也正在运行中。
c。这两个对象是在程序实时运行时创建的(我的是脱机版本,它在我自己的main.cpp中运行它的特定部分。

我的问题:
1。什么是音高弯曲?
2.如何将音高值转换为弯曲值?映射关系是什么?

我已经在谷歌上寻找解决方案,但没有找到明确的答案。

#1 楼

MIDI的核心是将音乐表示为离散的音符事件,每个音符具有静态音高。这非常适合代表键盘乐器上演奏的音乐。您可以使用以下格式将与调音阶上的音符相对应的任何频率转换为MIDI音符编号:

$ 69 + 12 \ times \ log_2 \ frac {frequency} {440} $

在MIDI接收器已针对A4 = 440 Hz进行校准的假设下。

这种表示形式对钢琴音乐是可以的,但问题是如何表示未映射到调律音阶的音高(非西方音乐,非音乐声音),以及如何表示音符持续时间内的音高变化(glissando,颤音)。

这是通过在MIDI中使用“音高弯曲消息”完成的,指示合成器将当前演奏音符的音调偏移一小段时间。默认情况下,大多数合成器都会在弯音消息范围(0 .. 16383)范围内针对+/- 2个半音进行校准。 8192对应于没有音高弯曲-发出的音高恰好是音符值的音高。音高弯曲值和频移比之间的映射由下式给出:

$ \ frac {f_ {emitted \ _note}} {f_ {note \ _message}} = 2 ^ {\ frac {弯音-8192} {4096 \ times 12}} $

因此您可以从下式获得合成器演奏的音符的频率:

$ 440 \ times 2 ^ {\ frac {note-69} {12.0} + \ frac {pitchbend-8192} {4096 \ times 12}} $

其中note是最后接收到的7位MIDI音符编号注意消息;弯音是最后收到的弯音消息的14位值。合成器首先将其弯音寄存器设置为8192,并且在接收到“重置所有控制器”消息期间也将重置该值。您想要用以下频率轨迹表示长笛颤音:500 Hz,510 Hz,500 Hz,作为MIDI消息。

基本注释编号为:

$ round(69 + 12 \ times \ log_2(500/440))= 71 $。

因此,您发送“ note on”消息,其注释号等于71。这等于音高:

$ 440 \ times 2 ^ {(71-69)/ 12} = 493.88 $

其中是回火刻度上最接近的音高。您需要发送音高弯曲消息以将音高提高以下倍数:

$ \ frac {500} {493.88} = 1.0124 $

并获得500 Hz 。相应的弯音值是:

$ round(8192 + 4096 \ times 12 \ times log_2 1.0124)= 9065 $

要获得510 Hz,请使用弯音值将会是:

$ round(8192 + 4096 \ times 12 \ times log_2 \ frac {510} {493.88})= 10469 $

因此您的MIDI消息序列500、510、500 Hz为:


注71
弯头9065
...
弯头10469
.. 。
弯音9065

您可以将MIDI音符编号视为音高的“整体”部分;并将音高弯曲作为音高的多余“小数”部分。

评论


$ \ begingroup $
另外,根据我对代码的理解,ge是弯音消息; ge.data [2]的MSB和ge.data [1]的LSB。 ananya是消息上的注释,ananya.data [1]是注释编号,ananya.data [2]是速度。除了时髦的变量命名似乎暗示着代码作者之间隐藏的浪漫外,我在这里还看到了潜在的WTF:1.0653f和11.0f常量有些麻烦。可读的选择是:1.05946f和12.0f。或1.06504f和11.0f。作者似乎假设音高弯曲范围为+/- 1个八度,这是另一个潜在的WTF。
$ \ endgroup $
–小食
2012年6月6日15:19



$ \ begingroup $
ROTFL上的“隐藏的浪漫”部分!我认为我没有正确地理解这一点,所以请多多包涵。音调值是从函数autocorrelate获得的,在我看来,这就像是输出的MIDI Note。注意公式中的midi2pitch数组吗?如果我是对的,那意味着我仍然没有弯曲值或音高的实际值来估计弯曲值,除非我有MIDI文件,否则也无法获得它们。一个简单的例子,变量太多,方程太少。在这种情况下,如何估算弯曲度,实际螺距值和速度?
$ \ endgroup $
–斯里拉姆
2012年3月7日在12:06

$ \ begingroup $
您想做什么?将音高/功率对转换为MIDI消息?还是将MIDI数据转换为实际音高?上面给出的代码将一对传入的MIDI音符+弯音消息(ananya msg,ge msg)转换为句点(音高变量)和功率(功率变量)。我认为这是用MIDI键盘控制的合成音源代替LPC激励-一种粗糙的声码器或自动调谐效果。
$ \ endgroup $
–小食
2012年7月7日12:15



$ \ begingroup $
快速浏览rt_lpc.cpp确认输入的0xe0类型MIDI消息(PITCH BEND)正在更新弯音值;并将输入的0x90类型MIDI消息(NOTE ON)复制到“ ananya”消息中。从那里开始,使用这些值完成使用修改音高的重新合成。不确定您要从那里做什么。
$ \ endgroup $
–小食
2012年3月7日,12:19

$ \ begingroup $
是的,对于创意信号转换,MIDI输入是完全不同的东西。它不是常规LPC分析/综合链的一部分;而是允许从键盘读取某些参数(音高和功率),而不是由分析模块产生这些参数。也许您可以发布一些带有音频文件示例的新问题,并提取以Hz为单位的音高轨迹,以便我们使您适应更强大的音高估计技术。 Aubio库中有一些音高跟踪器的变体。
$ \ endgroup $
–小食
2012年3月7日13:30

#2 楼

MIDI是允许(主要)合成器控制或由其他合成器或计算机控制的协议。

这是一种串行协议,允许交换消息,例如“ C1键向上”,“ D4键向下” “键速度,“音调变化”等。许多控制器都有一个“音调轮”,它是操纵杆或调音轮。这些使演奏者可以交互地更改当前弹奏的音调,以手动创建颤音或连续“滑音”从一个音符到另一个音符。吉他演奏者经常通过用左手弯曲琴弦来完成音调,因此通常称为音高弯曲,因此得名。

MIDI音高弯曲消息是一种传达在任何给定时间点应该发生多少音高变化的方法;接收到音高弯曲消息的合成器(软件或硬件)应该将给定数量的当前所有音符的音高改变。 />
控制器消息具有参数tha t从-8192到8191,在标准MIDI文件中,它应该涵盖从-200分到200分的范围,其中1分是半音的1/100,即比率2 ^(1/1200)= 1.000577789506555 。示例:要创建一个向下的音调偏移以达到标称频率的93%,在这种情况下,控制器值应为

c = round(log2(.93)*12*8192/2);


或-5146。您想要的比率为0.93,每个八度音阶的半音数为12,最大音高弯曲范围为2(在这种情况下为200 cent或2个半音),对数为log2()以2为底。

但是,在大多数合成器中,该范围是可配置的,并且假设所有合成器的行为均相同可能不是一个好主意。

下面的转换表可能会有所帮助。
http:// www.elvenminstrel.com/music/tuning/reference/pitchbends.shtml