Computing Bioacoustic
# Install and load required packages
packages <- c("tuneR", "soundecology", "seewave")
installed <- installed.packages()[, "Package"]
new_packages <- packages[!packages %in% installed]
if (length(new_packages) > 0) install.packages(new_packages)
library(tuneR)
## Warning: package 'tuneR' was built under R version 4.3.3
## Warning: package 'soundecology' was built under R version 4.3.3
## Warning: package 'seewave' was built under R version 4.3.3
# Step 1: Read the audio file (ensure the correct file path)
audio_path <- "C:/Users/lenovo/Downloads/DATA ZOOM H2N-20241003T073619Z-001/DATA ZOOM H2N/ZOOM0022 (Petak 5).WAV"
# Ensure the file exists before proceeding
if (!file.exists(audio_path)) stop("File not found: ", audio_path)
audio <- tryCatch({
readWave(audio_path)
}, error = function(e) {
stop("Failed to read audio file: ", e$message)
})
# Display the metadata of the audio file to verify the file has been loaded correctly
print(audio)
##
## Wave Object
## Number of Samples: 13622400
## Duration (seconds): 308.9
## Samplingrate (Hertz): 44100
## Channels (Mono/Stereo): Stereo
## PCM (integer format): TRUE
## Bit (8/16/24/32/64): 16
# Define processing parameters
segment_duration <- 60 # Duration of each segment in seconds
samples_per_segment <- segment_duration * audio@samp.rate # Number of samples per segment
# Define frequency ranges for sonotyping
anthrophony_range <- c(0, 255) # Human-made sounds
biophony_range <- c(1001, 5000) # Biological sounds
geophony_range <- c(256, 1000) # Natural, non-biological sounds
# Initialize counters for each sound type
anthrophony_count <- 0
biophony_count <- 0
geophony_count <- 0
# Initialize total time counters for each sound type
anthrophony_total_time <- 0
biophony_total_time <- 0
geophony_total_time <- 0
# Initialize lists to store bioacoustic indices
aei_values <- c()
ndsi_values <- c()
adi_values <- c()
bioacoustic_index_values <- c()
# Calculate the number of segments
num_segments <- ceiling(length(audio@left) / samples_per_segment)
# Loop over segments and process each one
for (i in 1:num_segments) {
start_sample <- ((i - 1) * samples_per_segment) + 1
end_sample <- min(i * samples_per_segment, length(audio@left))
# Extract the segment
segment_left <- audio@left[start_sample:end_sample]
# Ensure the segment has enough data
if (length(segment_left) < 1024) { # Adjust minimum length requirement
message(paste("Segment", i, "is too short for analysis, skipping..."))
next
}
# Create the segment object
segment <- Wave(left = segment_left, right = segment_left, samp.rate = audio@samp.rate, bit = audio@bit)
# Calculate mean amplitude of the segment
mean_amplitude <- mean(abs(segment_left)) # Using absolute values to avoid negative amplitudes
# ---- Sonotyping Analysis ---- #
fft_segment <- fft(segment@left)
n <- length(segment@left)
frequencies <- seq(0, segment@samp.rate / 2, length.out = floor(n / 2) + 1)
magnitude <- Mod(fft_segment)[1:(floor(n / 2) + 1)]
# Extract the dominant frequency (frequency with the highest magnitude)
dominant_freq <- frequencies[which.max(magnitude)]
sonotype <- "Unknown"
if (exists("dominant_freq")) {
# Classification based on dominant frequency
if (dominant_freq >= anthrophony_range[1] && dominant_freq <= anthrophony_range[2]) {
sonotype <- "Anthrophony (Human-made noise)"
anthrophony_count <- anthrophony_count + 1
anthrophony_total_time <- anthrophony_total_time + segment_duration
} else if (dominant_freq >= biophony_range[1] && dominant_freq <= biophony_range[2]) {
sonotype <- "Biophony (Biological sounds)"
biophony_count <- biophony_count + 1
biophony_total_time <- biophony_total_time + segment_duration
} else if (dominant_freq >= geophony_range[1] && dominant_freq <= geophony_range[2]) {
sonotype <- "Geophony (Natural non-biological sounds)"
geophony_count <- geophony_count + 1
geophony_total_time <- geophony_total_time + segment_duration
}
}
# Calculate the time (in minutes) from the start of the audio file
segment_time_minutes <- (start_sample - 1) / audio@samp.rate / 60
# ---- Plot the Spectrogram for the segment ---- #
tryCatch({
par(mfrow = c(1, 1)) # Reset to single plot
par(mar = c(4, 4, 2, 1)) # Set margins for the plot
spectro(segment, f = audio@samp.rate, flim = c(0, 5),
main = paste("Spectrogram of Segment", i), collevels = seq(-40, 0, 1))
}, error = function(e) {
message("Error in Spectrogram for segment ", i, ": ", e$message)
})
# Log the mean amplitude, dominant frequency, time (in minutes), and sonotype
message(paste("Segment", i, "Time (minutes):", round(segment_time_minutes, 2),
"- Mean Amplitude:", round(mean_amplitude, 4),
"- Dominant Frequency:", round(dominant_freq, 2), "Hz",
"- Sonotype:", sonotype))
# ---- Plot the Oscillogram for the segment ---- #
tryCatch({
par(mfrow = c(1, 1)) # Reset to single plot
par(mar = c(4, 4, 2, 1)) # Set margins for the plot
plot(seq_along(segment@left) / segment@samp.rate, segment@left, type = "l",
main = paste("Oscillogram of Segment", i), xlab = "Time (seconds)", ylab = "Amplitude")
}, error = function(e) {
message("Error in Oscillogram for segment ", i, ": ", e$message)
})
# ---- FFT of the Audio Segment ---- #
tryCatch({
par(mfrow = c(1, 1)) # Reset to single plot
par(mar = c(4, 4, 2, 1)) # Set margins for the FFT plot
plot(frequencies, magnitude, type = "l", main = paste("FFT of Segment", i),
xlab = "Frequency (Hz)", ylab = "Magnitude", col = "black", lwd = 2)
}, error = function(e) {
message("Error in FFT for segment ", i, ": ", e$message)
})
# ---- Calculate Bioacoustic Indices ---- #
tryCatch({
aei_result <- acoustic_evenness(segment)
ndsi_result <- ndsi(segment)
adi_result <- acoustic_diversity(segment)
bioacoustic_result <- bioacoustic_index(segment)
# Store the results
aei_values <- c(aei_values, mean(c(aei_result$left, aei_result$right)))
ndsi_values <- c(ndsi_values, mean(c(ndsi_result$left, ndsi_result$right)))
adi_values <- c(adi_values, mean(c(adi_result$left, adi_result$right)))
bioacoustic_index_values <- c(bioacoustic_index_values, mean(c(bioacoustic_result$left, bioacoustic_result$right)))
}, error = function(e) {
message("Error in calculating bioacoustic indices for segment ", i, ": ", e$message)
})
}
## Segment 1 Time (minutes): 0 - Mean Amplitude: 161.3197 - Dominant Frequency: 38.12 Hz - Sonotype: Anthrophony (Human-made noise)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.159749
## Right channel: 0.159749
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.8963975
## Right channel: 0.8963975
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.236363
## Right channel: 2.236363
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 2.022391
## Right channel: 2.022391
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

## Segment 2 Time (minutes): 1 - Mean Amplitude: 56.6093 - Dominant Frequency: 38.12 Hz - Sonotype: Anthrophony (Human-made noise)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.201925
## Right channel: 0.201925
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.5590755
## Right channel: 0.5590755
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.238294
## Right channel: 2.238294
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 2.205467
## Right channel: 2.205467
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

## Segment 3 Time (minutes): 2 - Mean Amplitude: 62.8684 - Dominant Frequency: 38.12 Hz - Sonotype: Anthrophony (Human-made noise)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.067771
## Right channel: 0.067771
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.4390927
## Right channel: 0.4390927
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.295375
## Right channel: 2.295375
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 2.718499
## Right channel: 2.718499
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

## Segment 4 Time (minutes): 3 - Mean Amplitude: 72.0633 - Dominant Frequency: 38.12 Hz - Sonotype: Anthrophony (Human-made noise)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.137998
## Right channel: 0.137998
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.452111
## Right channel: 0.452111
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.272868
## Right channel: 2.272868
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 2.616688
## Right channel: 2.616688
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

## This took quite a lot of time to display this graphic, you may set 'fastdisp=TRUE' for a faster, but less accurate, display
## Segment 5 Time (minutes): 4 - Mean Amplitude: 90.911 - Dominant Frequency: 38.12 Hz - Sonotype: Anthrophony (Human-made noise)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.155639
## Right channel: 0.155639
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.6137915
## Right channel: 0.6137915
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.264599
## Right channel: 2.264599
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 2.444244
## Right channel: 2.444244
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

## Segment 6 Time (minutes): 5 - Mean Amplitude: 332.1001 - Dominant Frequency: 4577.12 Hz - Sonotype: Biophony (Biological sounds)


##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Evenness Index:
## Left channel: 0.02414
## Right channel: 0.02414
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
## Normalized Difference Soundscape Index:
##
## Left channel: 0.9078794
## Right channel: 0.9078794
##
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Acoustic Diversity Index:
## Left channel: 2.301468
## Right channel: 2.301468
##
## This is a stereo file. Results will be given for each channel.
##
## Calculating index. Please wait...
##
## Bioacoustic Index:
## Left channel: 3.091766
## Right channel: 3.091766
## Warning in mean.default(c(aei_result$left, aei_result$right)): argument is not
## numeric or logical: returning NA
## Warning in mean.default(c(ndsi_result$left, ndsi_result$right)): argument is
## not numeric or logical: returning NA
## Warning in mean.default(c(adi_result$left, adi_result$right)): argument is not
## numeric or logical: returning NA

# ---- Summary of Results ---- #
# Calculate the frequency of occurrence for each sound type
anthrophony_frequency <- anthrophony_count / num_segments * 100 # in percentage
biophony_frequency <- biophony_count / num_segments * 100 # in percentage
geophony_frequency <- geophony_count / num_segments * 100 # in percentage
# Display the results
cat("\nSummary of Sonotyping and Bioacoustic Index Analysis:\n")
##
## Summary of Sonotyping and Bioacoustic Index Analysis:
cat("Anthrophony Frequency of Occurrence:", round(anthrophony_frequency, 2), "%\n")
## Anthrophony Frequency of Occurrence: 83.33 %
cat("Biophony Frequency of Occurrence:", round(biophony_frequency, 2), "%\n")
## Biophony Frequency of Occurrence: 16.67 %
cat("Geophony Frequency of Occurrence:", round(geophony_frequency, 2), "%\n")
## Geophony Frequency of Occurrence: 0 %
# ---- Bar Plot ---- #
# Plot the bar chart with margins adjusted for RMarkdown
bar_positions <- barplot(
c(anthrophony_frequency, biophony_frequency, geophony_frequency),
names.arg = c("Anthrophony", "Biophony", "Geophony"),
col = c('#FF0000', '#008000', '#0000FF'),
ylim = c(0, 100),
main = "Distribution of Sound Types",
xlab = "Sound Types",
ylab = "Frequency (%)",
space = 0.8
)
# Add text on the bars to display the percentage
text(
x = bar_positions,
y = c(anthrophony_frequency, biophony_frequency, geophony_frequency) + 5,
labels = paste0(round(c(anthrophony_frequency, biophony_frequency, geophony_frequency), 2), "%")
)
