我正在使用node.js进行项目。 该项目是将单词转换为数字,然后采用这些数字并创建音频输出。 音频输出应将数字作为频率播放。例如,我有一个数字数组[913,250,352],现在我想将这些数字作为频率播放。 我知道我可以在浏览器中使用音频API或任何其他允许我这样做的第三方程序包来播放它们。 问题是我想创建一些音频文件,我尝试将这些数字转换为音符,然后将其保存为Midi文件,我成功了,但问题是midi文件采用了频率,将它们转换为最接近的音符(示例:913会转换为932.33HZ-即音符编号81),
// add a track
var array = gematriaArray
var count = 0
var track = midi.addTrack()
var note
for (var i = 0; i < array.length; i++) {
note = array[i]
track = track.addNote({
//here im converting the freq -> midi note.
midi: ftom(parseInt(note)),
time: count,
duration: 3
})
count++
}
// write the output
fs.writeFileSync('./public/sounds/' + name + random + '.mid', new Buffer.from(midi.toArray()))
我搜索了互联网,但找不到任何可以帮助的东西。 我真的很想拥有一个用户可以下载这些文件作为频率的文件,有人知道该怎么做才能得到这个结果?
提前感谢助手。
答案 0 :(得分:1)
此功能将使用浮点值填充缓冲区,该浮点值表示给定频率下原始音频曲线的高度
var pop_audio_buffer_custom = function (number_of_samples, given_freq, samples_per_second) {
var number_of_samples = Math.round(number_of_samples);
var audio_obj = {};
var source_buffer = new Float32Array(number_of_samples);
audio_obj.buffer = source_buffer;
var incr_theta = (2.0 * Math.PI * given_freq) / samples_per_second;
var theta = 0.0;
for (var curr_sample = 0; curr_sample < number_of_samples; curr_sample++) {
audio_obj.buffer[curr_sample] = Math.sin(theta);
console.log(audio_obj.buffer[curr_sample] , "theta ", theta);
theta += incr_theta;
}
return audio_obj;
}; // pop_audio_buffer_custom
var number_of_samples = 10000; // long enough to be audible
var given_freq = 300;
var samples_per_second = 44100; // CD quality sample rate
var wav_output_filename = "/tmp/wav_output_filename.wav"
var synthesized_obj = {};
synthesized_obj.buffer = pop_audio_buffer_custom(number_of_samples, given_freq, samples_per_second);
数字音频世界是不平凡的……一旦有了音频缓冲区,下一步就是将浮点表示形式转换为可以存储为字节的形式(通常为16位整数,具体取决于您选择的位深度) )...那么需要将16位整数缓冲区作为WAV文件写出
音频是有时被称为时间序列的波浪……当您将拳头砸在桌子上时,桌子上下摆动,从而使微小的空气分子与该摆动一致地推动……空气的摆动在整个房间中传播。并到达麦克风振膜或您的耳膜,然后在此波的作用下摆动……如果您将铅笔粘在振膜上,使其随振膜一起摇摆,然后慢慢地将纸条沿振膜的前端滑动铅笔,您会看到一条曲线写在该纸条上……这是音频曲线……音频样本只是该曲线在瞬间的高度……如果您反复记下该曲线的高度值以恒定速率每秒X次,您将获得原始音频的数据点列表(这是上面的函数创建的)...因此,给定的音频样本只是给定时间点上音频曲线高度的值...由于计算机不是连续的,而是光盘他们无法处理整个铅笔绘制的曲线,因此只关心此瞬时测量的曲线高度值列表...这些是音频样本
可以将以下32位浮点缓冲区输入以下函数,以返回16位整数缓冲区
var convert_32_bit_float_into_signed_16_bit_int_lossy = function(input_32_bit_buffer) {
// this method is LOSSY - intended as preliminary step when saving audio into WAV format files
// output is a byte array where the 16 bit output format
// is spread across two bytes in little endian ordering
var size_source_buffer = input_32_bit_buffer.length;
var buffer_byte_array = new Int16Array(size_source_buffer * 2); // Int8Array 8-bit twos complement signed integer
var value_16_bit_signed_int;
var index_byte = 0;
console.log("size_source_buffer", size_source_buffer);
for (var index = 0; index < size_source_buffer; index++) {
value_16_bit_signed_int = ~~((0 < input_32_bit_buffer[index]) ? input_32_bit_buffer[index] * 0x7FFF :
input_32_bit_buffer[index] * 0x8000);
buffer_byte_array[index_byte] = value_16_bit_signed_int & 0xFF; // bitwise AND operation to pluck out only the least significant byte
var byte_two_of_two = (value_16_bit_signed_int >> 8); // bit shift down to access the most significant byte
buffer_byte_array[index_byte + 1] = byte_two_of_two;
index_byte += 2;
};
// ---
return buffer_byte_array;
};
下一步是将16位int缓冲区以上的内容持久保存到wav文件中……我建议您为此使用许多nodejs库之一(或者最好将其自己编写为仅两页代码;-)) )