【发布时间】:2019-05-10 20:02:32
【问题描述】:
我有一个小应用程序可以接受来自互联网的传入音频流,我正在尝试查找音调或连续哔声的频率。在提示音/哔声时,它是唯一会播放的东西。其余的音频是静音或说话。我正在使用 node-pitchfinder npm 模块来查找音调,当我使用我制作的 2,000Hz 的示例音频剪辑时,应用程序会打印出一到两赫兹内的频率。当我将音频流拉到网上时,我不断得到像 17,000 Hz 这样的结果。我的猜测是音频信号中有一些“噪音”,这就是 node-pitchfinder 模块正在接收的内容。
有什么方法可以实时滤除噪音以获得准确的频率?
流式音频文件为:http://relay.broadcastify.com/fq85hty701gnm4z.mp3
代码如下:
const fs = require('fs');
const fsa = require('fs-extra');
const Lame = require('lame');
const Speaker = require('speaker');
const Volume = require('pcm-volume');
const Analyser = require('audio-analyser')
const request = require('request')
const Chunker = require('stream-chunker');
const { YIN } = require('node-pitchfinder')
const detectPitch = YIN({ sampleRate: 44100})
//const BUFSIZE = 64;
const BUFSIZE = 500;
var decoder = new Lame.Decoder();
decoder.on('format', function(format){onFormat(format)});
var chunker = Chunker(BUFSIZE);
chunker.pipe(decoder);
var options = {
url: 'http://relay.broadcastify.com/fq85hty701gnm4z.mp3',
headers: {
"Upgrade-Insecure-Requests": 1,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15"
}
}
var audio_stream = request(options);
//var audio_stream = fs.createReadStream('./2000.mp3');
audio_stream.pipe(chunker);
function onFormat(format)
{
//if (volume == "undefined")
volume = 1.0;
vol = new Volume(volume);
speaker = new Speaker(format);
analyser = createAnalyser(format);
analyser.on('data', sample);
console.log(format);
vol.pipe(speaker);
vol.pipe(analyser);
decoder.pipe(vol);
vol.setVolume(volume);
}
function createAnalyser(format)
{
return new Analyser({
fftSize: 8,
bufferSize: BUFSIZE,
'pcm-stream': {
channels: format.channels,
sampleRate: format.sampleRate,
bitDepth: format.bitDepth
}
});
}
var logFile = 'log.txt';
var logOptions = {flag: 'a'};
function sample()
{
if (analyser) {
const frequency = detectPitch(analyser._data)
console.log(frequency)
}
}
我的目标是在一大块数据中找到最主要的音频频率,以便找出音调。
我发现了一些据说是用 python 做的代码
def getFreq( pkt ):
#Use FFT to determine the peak frequency of the last chunk
thefreq = 0
if len(pkt) == bufferSize*swidth:
indata = np.array(wave.struct.unpack("%dh"%(len(pkt)/swidth), pkt))*window
# filter out everything outside of our bandpass Hz
bp = np.fft.rfft(indata)
minFilterBin = (bandPass[0]/(sampleRate/bufferSize)) + 1
maxFilterBin = (bandPass[1]/(sampleRate/bufferSize)) - 1
for i in range(len(bp)):
if i < minFilterBin:
bp[i] = 0
if i > maxFilterBin:
bp[i] = 0
# Take the fft and square each value
fftData = abs(bp)**2
# find the maximum
which = fftData[1:].argmax() + 1
# Compute the magnitude of the sample we found
dB = 10*np.log10(1e-20+abs(bp[which]))
#avgdB = 10*np.log10(1e-20+abs(bp[which - 10:which + 10].mean()))
if dB >= minDbLevel:
# use quadratic interpolation around the max
if which != len(fftData)-1:
warnings.simplefilter("error")
try:
y0, y1, y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
except RuntimeWarning:
return(-1)
# find the frequency and output it
warnings.simplefilter("always")
thefreq = (which + x1) * sampleRate/bufferSize
else:
thefreq = which * sampleRate/bufferSize
else:
thefreq = -1
return(thefreq)
【问题讨论】:
-
当我连接到您在问题中提供的链接时,我收到以下错误
The file you requested could not be found。您能否提供您要分析的流的可下载 mp3 文件? -
@Marius 看起来网站会不时更改 URL...这个目前正在运行:relay.broadcastify.com/m14td6p27nghf8r.mp3 如果这不起作用,您可以在此处找到流的链接: broadcastify.com/listen/feed/14082(大部分时间都是沉默的)。 “音调”的一个例子是:edispatches.com/orgs/general/…
-
我下载了 mp3,发现 mp3 的采样率为 11025Hz(但在上面的代码中,音高检测器的采样率设置为 44100Hz
YIN({ sampleRate: 44100}))。如果我将采样率调整为 11025Hz,那么我会得到大约 2200Hz 的输出。这会是预期的结果吗? -
@Marius 下载的文件只是音调的一个示例。最终,我将从具有 44100 采样率的流式 mp3 文件中获取数据。很抱歉造成混乱
-
当我在 VLC 中打开流式 mp3 文件时,我得到 22050 的采样率。我建议使用流中的采样率初始化
onFormat中的音高检测算法。
标签: javascript node.js audio audio-streaming pcm