The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Acoustic (audio) recordings use the bioacoustics
flavor of Camtrap DP. Audio data is
media-based (observationLevel = "media"):
each observation refers to a media file (mediaID). The
differences from the camera-trap schema are read automatically from the
bioacoustics schemas; the main ones are:
device* fields (deviceID,
deviceModel, …) plus elevation,
devicePlatform, recordingSchedule,
locationType.duration,
samplingFrequency, bitDepth,
gain, channels; fileMediatype is
an audio type such as audio/wav.frequencyLow,
frequencyHigh; cameraSetupType becomes
deviceSetupType.deployments use %Y-%m-%dT%H:%M:%S%z (no
fractional seconds); media / observations
timestamps use fractional seconds
%Y-%m-%dT%H:%M:%S.%f%z.project$captureMethod for audio is one of
activityDetection, continuous,
recordingSchedule (not timeLapse).Tip — pass datetimes as
POSIXct. The package then formats each table’s datetime correctly (offset+0900, and.000fractional seconds where the schema requires them). A raw string like"2026/6/12 12:00:00"is written as-is and fails validation.
This example assumes you have only two field notebooks — a
deployment notebook and an observation
notebook — and that the observation notebook carries the audio
file names, from which media is
derived.
data("Adep") # deployment field-notebook (one row per device deployment)
data("Aobs") # observation field-notebook (one row per observation; has `filename`)
str(Adep, vec.len = 2)
#> 'data.frame': 2 obs. of 14 variables:
#> $ deploymentID : chr "AC01" "AC02"
#> $ longitude : num 139 139
#> $ latitude : num 34.9 34.9
#> $ locationID : chr "L01" "L02"
#> $ startDate : chr "2026-06-12" "2026-06-13"
#> $ startTime : chr "06:00:00" "06:00:00"
#> $ endDate : chr "2026-06-20" "2026-06-21"
#> $ endTime : chr "06:00:00" "06:00:00"
#> $ deviceID : chr "AM1" "AM2"
#> $ deviceModel : chr "AudioMoth 1.2.0" "AudioMoth 1.2.0"
#> $ samplingFrequency: int 48000 48000
#> $ bitDepth : int 16 16
#> $ channels : int 1 1
#> $ setupBy : chr "Jane Doe" "Jane Doe"
str(Aobs, vec.len = 2)
#> 'data.frame': 6 obs. of 19 variables:
#> $ institutionCode: chr "NIES" "NIES" ...
#> $ collectionCode : chr "ACO" "ACO" ...
#> $ obsID : chr "1" "2" ...
#> $ eventID : chr "e1" "e1" ...
#> $ deploymentID : chr "AC01" "AC01" ...
#> $ locationID : chr "L01" "L01" ...
#> $ date : chr "2026-06-12" "2026-06-12" ...
#> $ time : chr "06:00:00" "06:00:00" ...
#> $ filename : chr "AM1_20260612_060000.wav" "AM1_20260612_060000.wav" ...
#> $ duration : num 60 60 60 60 60 ...
#> $ object : chr "animal" "animal" ...
#> $ class : chr "Aves" "Aves" ...
#> $ genus : chr "Strix" "Cuculus" ...
#> $ species : chr "uralensis" "canorus" ...
#> $ individualCount: int NA NA NA NA NA ...
#> $ frequencyLow : num 300 500 300 NA 500 ...
#> $ frequencyHigh : num 900 900 900 NA 900 ...
#> $ eventStart : chr "2026-06-12 06:00:05" "2026-06-12 06:00:12" ...
#> $ eventEnd : chr "2026-06-12 06:00:09" "2026-06-12 06:00:18" ...Adep has deploymentID, coordinates,
startDate/startTime,
endDate/endTime, deviceID,
deviceModel, the recording settings
(samplingFrequency, bitDepth,
channels) and setupBy. Aobs has
deploymentID, filename,
date/time, duration, the taxonomy
(class/genus/species),
individualCount,
frequencyLow/frequencyHigh and
eventStart/eventEnd. In this example data the
coordinates fall in the Izu Peninsula (Japan),
individualCount is NA (not counted from
audio), and frequencyLow/frequencyHigh use
approximate values from the literature.
ba <- "https://raw.githubusercontent.com/camera-traps/bioacoustics/main/camtrap-dp/1.0.2/%s"
dp <- R6_CamtrapDP$new(version = "1.0.2",
title = "Acoustic survey example", description = "AudioMoth recordings",
id = "https://example.org/dataset/acoustic-1")
dp$set_properties(
version = "1.0.2",
profile = sprintf(ba, "camtrap-dp-profile-acoustic.json"),
schema_urls = list(
deployments = sprintf(ba, "deployments-table-schema-acoustic.json"),
media = sprintf(ba, "media-table-schema-acoustic.json"),
observations = sprintf(ba, "observations-table-schema-acoustic.json")))Build the deployments table from Adep. Combine the date
and time columns into POSIXct so the package writes the
correct datetime format.
deployments <- data.frame(
deploymentID = Adep$deploymentID,
latitude = Adep$latitude,
longitude = Adep$longitude,
locationID = Adep$locationID,
deploymentStart = as.POSIXct(paste(Adep$startDate, Adep$startTime), tz = "Asia/Tokyo"),
deploymentEnd = as.POSIXct(paste(Adep$endDate, Adep$endTime), tz = "Asia/Tokyo"),
deviceID = Adep$deviceID,
deviceModel = Adep$deviceModel,
setupBy = Adep$setupBy,
stringsAsFactors = FALSE)There is no separate media notebook: build media from
the unique filenames in Aobs (one row per
audio file), and bring the recording settings over from
Adep.
files <- Aobs[!duplicated(Aobs$filename), ] # one row per audio file
media <- data.frame(
mediaID = files$filename, # the file name is the media identifier
deploymentID = files$deploymentID,
timestamp = as.POSIXct(paste(files$date, files$time), tz = "Asia/Tokyo"),
filePath = file.path("audio", files$filename),
filePublic = TRUE,
fileMediatype = paste0("audio/", tolower(tools::file_ext(files$filename))), # "audio/wav"
duration = files$duration,
stringsAsFactors = FALSE)
# add device recording settings (samplingFrequency / bitDepth / channels) from Adep
media <- merge(media, Adep[, c("deploymentID", "samplingFrequency", "bitDepth", "channels")],
by = "deploymentID", all.x = TRUE)
head(media)
#> deploymentID mediaID timestamp
#> 1 AC01 AM1_20260612_060000.wav 2026-06-12 06:00:00
#> 2 AC01 AM1_20260612_063000.wav 2026-06-12 06:30:00
#> 3 AC01 AM1_20260613_060000.wav 2026-06-13 06:00:00
#> 4 AC02 AM2_20260613_060000.wav 2026-06-13 06:00:00
#> filePath filePublic fileMediatype duration
#> 1 audio/AM1_20260612_060000.wav TRUE audio/wav 60
#> 2 audio/AM1_20260612_063000.wav TRUE audio/wav 60
#> 3 audio/AM1_20260613_060000.wav TRUE audio/wav 60
#> 4 audio/AM2_20260613_060000.wav TRUE audio/wav 60
#> samplingFrequency bitDepth channels
#> 1 48000 16 1
#> 2 48000 16 1
#> 3 48000 16 1
#> 4 48000 16 1timestamp is written with fractional
seconds (e.g. 2026-06-12T06:00:00.000+0900) to match the
acoustic media format — handled automatically because it is
a POSIXct.
observations <- data.frame(
observationID = paste(Aobs$deploymentID, Aobs$eventID, Aobs$obsID, sep = "_"),
deploymentID = Aobs$deploymentID,
mediaID = Aobs$filename, # link to media (mediaID = filename)
eventStart = as.POSIXct(Aobs$eventStart, tz = "Asia/Tokyo"),
eventEnd = as.POSIXct(Aobs$eventEnd, tz = "Asia/Tokyo"),
observationLevel = "media",
observationType = ifelse(Aobs$object == "none", "blank",
ifelse(Aobs$object == "hito", "human", "animal")),
scientificName = ifelse(is.na(Aobs$genus), Aobs$class, paste(Aobs$genus, Aobs$species)),
count = Aobs$individualCount, # NA here (not counted from audio)
frequencyLow = Aobs$frequencyLow,
frequencyHigh = Aobs$frequencyHigh,
stringsAsFactors = FALSE)dp$add_contributors(data.frame(title = "Jane Doe", role = "contact",
organization = "NIES", stringsAsFactors = FALSE))
dp$add_license(name = "CC0-1.0", scope = "data")
dp$add_license(name = "CC-BY-4.0", scope = "media")
dp$set_project(title = "Acoustic survey", samplingDesign = "systematicRandom",
captureMethod = "recordingSchedule", individualAnimals = FALSE,
observationLevel = "media")
dp$set_st()
# dp$set_taxon() # taxonID from GBIF/ITIS/NCBI; requires the taxadb package + internet
dp$check_relations() # PK/FK; warns and points at datapackage$data$... if a key is missing
path <- file.path(tempdir(), "acoustic-package")
dp$out_camtrapdp(write = TRUE, directory = path)
issues <- dp$validate_frictionless(directory = path, python = "python") # pip install frictionless
ctdp_is_valid(issues)To validate a package that already exists on disk without overwriting it:
ba <- "https://raw.githubusercontent.com/camera-traps/bioacoustics/main/camtrap-dp/1.0.2/%s"
acoustic_media <- TableSchema$new(
"media", version = "1.0.2",
url_template = sprintf(ba, "media-table-schema-acoustic.json"))
acoustic_media$field_names()
acoustic_media$requirements() # type / format / required / enum per field
acoustic_media$field("timestamp")$format # "%Y-%m-%dT%H:%M:%S.%f%z"These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.