【问题标题】:Detect specific frequency in audio file using R使用 R 检测音频文件中的特定频率
【发布时间】:2020-02-27 02:32:31
【问题描述】:

我有一个蟋蟀唧唧喳喳的录音 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 

【问题讨论】:

  • 这是一个需要解决的有趣问题。如果您可以将文件托管在某个地方让其他人尝试找到解决方案,那就太好了。

标签: r audio pitch-detection


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    正如@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')
    

    结果如下所示。绿色竖线表示开始,红色竖线表示结束。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      相关资源
      最近更新 更多