1

我有一个蟋蟀唧唧喳喳的录音wav文件,每隔一段时间就会在大约20kHz处发生大约0.01秒的唧唧声。我想使用 R 来检测录制期间特定频率(20kHz)发生/开始的时间。

波对象

Number of Samples:      4041625
Duration (seconds):     91.65
Samplingrate (Hertz):   44100
Channels (Mono/Stereo): Mono
PCM (integer format):   TRUE
Bit (8/16/24/32/64):    16 
4

2 回答 2

1

我相信dfreqseewave包裹中得到的是你所追求的。该方法随时间(以秒为单位)返回主频率(幅度最高的频率)。以下是如何获取该信息的示例:

library(tuneR)
library(seewave)

# Read audio file
crickets <- readWave("~/crickets.wav")

# Get dominant frequency
d <- dfreq(crickets, plot = FALSE)

head(d)

#               x        y
# [1,] 0.00000000 0.000000
# [2,] 0.02332295 0.000000
# [3,] 0.04664589 0.000000
# [4,] 0.06996884 0.000000
# [5,] 0.09329179 0.000000
# [6,] 0.11661474 2.583984

于 2020-02-27T14:06:02.710 回答
1

正如@anddt 所说,dfreq这是一个不错的选择,尽管它通常需要对各种参数进行一些调整,例如thresholdwl。这是一个玩具示例,其中包含一些包含噪声的虚构数据。

library(seewave)
library(tuneR)

chirp = sine(freq = 20000, duration = 0.01, xunit = 'time')
silence_0.2 = silence(duration = 0.2, xunit = 'time')
silence_0.1 = silence(duration = 0.1, xunit = 'time')
noise_0.2 = noise(kind='pink', duration=0.2, xunit = 'time')
noise_0.1 = noise(kind='pink', duration=0.1, xunit = 'time')
signal = bind(silence_0.2, chirp, noise_0.1, silence_0.2, chirp, silence_0.1, noise_0.2, chirp, noise_0.2, silence_0.2)

# threshold removes noise, wl is the window length of the fourier transform, smaller 
# values give more accuracy for time but noise gets more troublesome
peaks = data.frame(dfreq(signal, threshold = 10, wl = 128, plot=F))
peaks[is.na(peaks)] = 0
names(peaks) = c('time', 'frequency')
peaks$frequency[peaks$frequency < 19.9 | peaks$frequency > 20.1] = 0

startindices = which(diff(peaks$frequency) > 19)
endindices = which(diff(peaks$frequency) < -19)
starttimes = peaks[startindices, 1]
endtimes = peaks[endindices, 1]

plot(signal, col='grey')
abline(v = starttimes, col='green')
abline(v = endtimes, col='red')

结果看起来像这样。绿色垂直线代表开始,红色垂直线代表啁啾结束。

在此处输入图像描述

于 2020-03-01T11:54:23.973 回答