Hey there!
I have some errors when I create the loop structure for the file. As a result, it gives data for only 1 row and also omits some columns in the output file.
I was looking through the script but I am unsure where I made an error.
Can anyone help, please?
This code was adapted from an already existing code labphon-9152-carignan.html
Script:
file_list <- unique(data$filename)
mfccs <- paste0("mfcc",1:14)
Loop through all files in file_list
for (file in file_list) {
Process each file's data
fdat <- data[data$filename == file, ]
}
Check if there’s data for the file
if (nrow(fdat) > 0) {
print(paste("Processing file:", file)) # Debugging print statement
}
Read the audio file
audio_dir <- "/Desktop/audio/"
wav_files <- list.files(audio_dir, pattern = "\.wav$", full.names = FALSE)
wav_file_name <- paste0(file, ".wav")
if (wav_file_name %in% wav_files) {
audio <- tuneR::readWave(paste0(audio_dir, wav_file_name))
}
total duration (in seconds)
totaldur <- length(audio@left)/audio@samp.rate
extract audio and de-mean to remove DC offset
snd <- audio@left - mean(audio@left)
audio pre-emphasis
for (n in 2:length(snd)) {
snd[n] <- snd[n] - 0.97*snd[n-1]
}
replace the wave object audio samples
audio@left <- snd
calculate MFCCs
melcs <- tuneR::melfcc(audio,
sr = audio@samp.rate,
numcep = length(mfccs),
wintime = 0.01,
hoptime = 0.005)
get the actual time step (may be slightly different than "hoptime")
timestep <- totaldur/nrow(melcs)
get the MFCCs samples nearest to the time points
mfsamps <- round(fdat$point_time/timestep)
add the MFCCs to the file data - corrected to as.list
fdat[,mfccs] <- as.list(melcs[mfsamps,])
create spectrogram
spec <- signal::specgram(x = audio@left,
n = 1024,
Fs = audio@samp.rate,
window = 256,
overlap = 128
)
get spectra
P <- abs(spec$S)
convert to dB
P <- 20*log10(P)
get the spectral time step
timestep <- diff(spec$t[1:2])
get the spectral samples nearest to the time points
specsamps <- round(fdat$point_time/timestep)
get first four spectral moments
moments <- c()
for (samp in 1:length(specsamps)) {
moments <- rbind(moments, emuR::moments(P[,samp]))
}
colnames(moments) <- c("COG", "variance", "skew", "kurtosis")
add the moments to the file data
fdat[,colnames(moments)] <- moments
nasal murmur (low/high ratio, 0-320 Hz : 320-5360 Hz) bands
thresh1 <- which.min(abs(spec$f-320))
thresh2 <- which.min(abs(spec$f-5360))
get the spectral amplitude means within the two frequency bands
print(specsamps)
specsamps <- 1:101
low <- colMeans(P[1:thresh1,specsamps])
high <- colMeans(P[thresh1:thresh2,specsamps])
calculate the murmur ratio and add to the file data
print(length(low))
print(length(high))
fdat$murmur <- rep(low / high, length.out = nrow(fdat))
fdat$murmur <- list(low/high)
add the file data to the combined data frame
alldata <- rbind.data.frame(alldata,fdat)
saveRDS(alldata,"alldata.Rda")