所以我设法通过使用 synth() 函数合成波来做到这一点。这通过数据帧的每一列工作,并在载波频率上创建幅度调制信号。然后,将所有列的结果相加。
library(seewave)
library(tuneR)
nsamps <- 600 # number of samples to create
sf <- 10 # sampling frequency of the data in Hz
fout <- 22000 # Sample frequency of output sound (Hz)
dout <- 10 # length of output sound file (seconds)
# some dummy amplitude data, 3 columns
df <- data.frame(f1 = sin((1:nsamps)/180*pi)+1, f2 = sin((1:nsamps)/180*pi + pi)+1, f3 = sin((1:nsamps)/90*pi)+1)
mat <- as.matrix(df)
freqs <- seq(100, 1000, length.out = ncol(mat)) # Carrier frequencies for each data column (Hz)
syn <- 0 # this is the synthesised wave
atemp <- seq(from=1, to=nrow(mat), length.out = fout*dout) # new times
for(ii in 1:ncol(mat)){ # for each data column
scale_data <- (mat[,ii] - min(mat[,ii]))/diff(range(mat[,ii])) # scale each column between 0 and 1, comment out for absolute amplitudes across all columns
amp <- approx(x = 1:nrow(mat), y = scale_data, xout = atemp)$y # sample the amplitude data onto the new times
syn <- syn + synth(f = fout, d = dout, cf = freqs[ii], output = 'wave', a = amp) # build up the total synth wave
}
wave <- Wave(left = syn, samp.rate=fout, bit=16) # create a wave class
listen(wave) # listen to the sound
这是创建频谱图的代码:
t_win <- 0.5 # window length for spectrogram (s)
n_win <- t_win/(nsamps/sf/dout)*fout # calculate the window length in samples
spectro(wave, f=fout, flim = c(0,1.1), wl = n_win, ovlp = 75) # plot the spectrogram