Skip to content

Commit

Permalink
Merge pull request #23 from TheCacophonyProject/fix-audio-mode
Browse files Browse the repository at this point in the history
various fixes to audio mode
  • Loading branch information
gferraro authored Jan 13, 2025
2 parents 8235d80 + ae37c1b commit ee4c5d7
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 55 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"rust-analyzer.cargo.target": "thumbv6m-none-eabi",
"rust-analyzer.check.allTargets": false,
"rust-analyzer.checkOnSave.allTargets": false,
"editor.formatOnSave": true,
"cortex-debug.variableUseNaturalFormat": true
Expand Down
24 changes: 14 additions & 10 deletions src/core0_audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,15 @@ pub fn audio_task(
);
alarm_date_time = Some(alarm);
if device_config_was_updated {
if !check_alarm_still_valid(
if !check_alarm_still_valid_with_thermal_window(
&alarm,
&synced_date_time.get_adjusted_dt(timer),
&device_config,
) {
//if window time changed and alarm is after rec window start
clear_audio_alarm(&mut flash_storage);
scheduled = false;
alarm_date_time = None;
info!("Rescehduling as alarm is after window start");
}
}
Expand Down Expand Up @@ -394,12 +395,14 @@ pub fn audio_task(

// should take recording now
event_logger.log_event(
LoggerEvent::new(
LoggerEventKind::Rp2040MissedAudioAlarm(alarm.timestamp_micros() as u64),
synced_date_time.get_timestamp_micros(&timer),
),
&mut flash_storage,
);
LoggerEvent::new(
LoggerEventKind::Rp2040MissedAudioAlarm(
alarm.and_utc().timestamp_micros() as u64,
),
synced_date_time.get_timestamp_micros(&timer),
),
&mut flash_storage,
);
recording_type = Some(RecordingType::ScheduledRecording);
}
}
Expand Down Expand Up @@ -810,7 +813,7 @@ pub fn schedule_audio_rec(
if alarm_enabled {
event_logger.log_event(
LoggerEvent::new(
LoggerEventKind::SetAlarm(wakeup.timestamp_micros() as u64),
LoggerEventKind::SetAlarm(wakeup.and_utc().timestamp_micros() as u64),
synced_date_time.get_timestamp_micros(&timer),
),
flash_storage,
Expand Down Expand Up @@ -857,15 +860,16 @@ fn should_offload_audio_recordings(
return false;
}

pub fn check_alarm_still_valid(
pub fn check_alarm_still_valid_with_thermal_window(
alarm: &NaiveDateTime,
now: &NaiveDateTime,
device_config: &DeviceConfig,
) -> bool {
// config has changed so check if not in audio only that alarm is still going to trigger on rec window start
if device_config.config().audio_mode != AudioMode::AudioOnly {
let (start, end) = device_config.next_or_current_recording_window(now);
//alarm before start or we are in rec window
return alarm <= &start || now >= &start;
}
false
true
}
61 changes: 33 additions & 28 deletions src/core1_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ use rp2040_hal::pio::PIOExt;
use rp2040_hal::timer::Instant;
use rp2040_hal::{Sio, Timer};

use crate::core0_audio::{check_alarm_still_valid, schedule_audio_rec, AlarmMode, MAX_GAP_MIN};
use crate::core0_audio::{
check_alarm_still_valid_with_thermal_window, schedule_audio_rec, AlarmMode, MAX_GAP_MIN,
};
#[repr(u32)]
#[derive(Format)]
pub enum Core1Task {
Expand Down Expand Up @@ -207,6 +209,7 @@ impl SyncedDateTime {
+ chrono::Duration::microseconds(
(timer.get_counter() - self.timer_offset).to_micros() as i64
))
.and_utc()
.timestamp_micros() as u64
}

Expand Down Expand Up @@ -446,40 +449,40 @@ pub fn core_1_task(
let mut next_audio_alarm: Option<NaiveDateTime> = None;

match device_config.config().audio_mode {
AudioMode::AudioAndThermal => {
AudioMode::AudioOrThermal | AudioMode::AudioAndThermal => {
let (audio_mode, audio_alarm) = get_audio_alarm(&mut flash_storage);
record_audio = true;
let mut schedule_alarm = true;

// if audio alarm is set check it's within 60 minutes and before or on thermal window start
if let Some(audio_alarm) = audio_alarm {
if let Ok(audio_mode) = audio_mode {
if audio_mode == AlarmMode::AUDIO {
schedule_alarm = false;
}
//otherwise alarm is for thermal so reschedule an audio alarm during recording window
}
if !schedule_alarm {
let synced = synced_date_time.date_time_utc;
let until_alarm = (audio_alarm - synced).num_minutes();
if until_alarm <= MAX_GAP_MIN as i64 {
info!(
"Audio alarm already scheduled for {}-{}-{} {}:{}",
audio_alarm.year(),
audio_alarm.month(),
audio_alarm.day(),
audio_alarm.hour(),
audio_alarm.minute()
);
if check_alarm_still_valid(&audio_alarm, &synced, &device_config) {
next_audio_alarm = Some(audio_alarm);
schedule_alarm = false;
let synced = synced_date_time.date_time_utc;
let until_alarm = (audio_alarm - synced).num_minutes();
if until_alarm <= MAX_GAP_MIN as i64 {
info!(
"Audio alarm already scheduled for {}-{}-{} {}:{}",
audio_alarm.year(),
audio_alarm.month(),
audio_alarm.day(),
audio_alarm.hour(),
audio_alarm.minute()
);
if check_alarm_still_valid_with_thermal_window(
&audio_alarm,
&synced,
&device_config,
) {
next_audio_alarm = Some(audio_alarm);
schedule_alarm = false;
} else {
schedule_alarm = true;
//if window time changed and alarm is after rec window start
info!("Rescehduling as alarm is after window start");
}
} else {
schedule_alarm = true;
//if window time changed and alarm is after rec window start
info!("Rescehduling as alarm is after window start");
info!("Alarm is missed");
}
} else {
info!("Alarm is missed");
}
}
}
Expand All @@ -501,6 +504,7 @@ pub fn core_1_task(
}
}
_ => {
info!("Clearing audio alarm");
clear_audio_alarm(&mut flash_storage);
record_audio = false
}
Expand Down Expand Up @@ -1324,7 +1328,8 @@ pub fn core_1_task(
event_logger.log_event(
LoggerEvent::new(
LoggerEventKind::SetAlarm(
next_recording_window_start.timestamp_micros() as u64,
next_recording_window_start.and_utc().timestamp_micros()
as u64,
),
synced_date_time.get_timestamp_micros(&timer),
),
Expand Down
2 changes: 1 addition & 1 deletion src/event_logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ pub fn write_audio_alarm(
let page_offset = 0;
let mut event_data = [0u8; 18];
event_data[0] = mode as u8;
LittleEndian::write_i64(&mut event_data[1..9], alarm_dt.timestamp_millis());
LittleEndian::write_i64(&mut event_data[1..9], alarm_dt.and_utc().timestamp_millis());
flash_storage.write_event(&event_data, AUDIO_BLOCK, AUDIO_PAGE, page_offset as u16);
}

Expand Down
9 changes: 4 additions & 5 deletions src/pdm_microphone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,11 @@ impl AudioBuffer {
}
pub fn slice_for(&mut self, raw_data_length: usize) -> &mut [u16] {
let end = self.index + raw_data_length / 8;
let slice;
if end > USER_BUFFER_LENGTH {
slice = &mut self.data[self.index..USER_BUFFER_LENGTH];
let slice = if end > USER_BUFFER_LENGTH {
&mut self.data[self.index..USER_BUFFER_LENGTH]
} else {
slice = &mut self.data[self.index..self.index + raw_data_length / 8];
}
&mut self.data[self.index..self.index + raw_data_length / 8]
};
self.index += slice.len();
return slice;
}
Expand Down
22 changes: 11 additions & 11 deletions src/pdmfilter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl PDMFilter {
let mut out_index = 0;

for i in (0..=data.len() - 8).step_by(PDM_DECIMATION as usize >> 3) {
let index = i as usize;
let index = i;
// 3 polyphase FIR?
let z0 = filter_table_mono_64(&self.lut, &data[index..index + 8], 0);
let z1 = filter_table_mono_64(&self.lut, &data[index..index + 8], 1);
Expand All @@ -112,7 +112,7 @@ impl PDMFilter {

self.coef[1] = self.coef[0] + z1 as u32;

self.coef[0] = z0 as u32;
self.coef[0] = z0;

old_out = (self.hp_alpha as i64 * (old_out + z - old_in)) >> 8;
old_in = z;
Expand All @@ -121,7 +121,7 @@ impl PDMFilter {
z = oldz * volume as i64;

z = round_div(z, self.div_const as i64);
z = satural_lh(z, -32700 as i64, 32700 as i64);
z = satural_lh(z, -32700_i64, 32700_i64);

if saveout {
dataout[out_index] = z as u16;
Expand Down Expand Up @@ -155,14 +155,14 @@ fn satural_lh(n: i64, l: i64, h: i64) -> i64 {
fn filter_table_mono_64(lut: &[u32], data: &[u8], s: u8) -> u32 {
let s_offset: usize = s as usize * 256 * 8;
// because of endiness the first byte of a 32 bit is at index 3, 2, 1 .. 0
return lut[s_offset + (data[3] as usize * PDM_DECIMATION as usize / 8) as usize]
+ lut[s_offset + (data[2] as usize * PDM_DECIMATION as usize / 8 + 1) as usize]
+ lut[s_offset + (data[1] as usize * PDM_DECIMATION as usize / 8 + 2) as usize]
+ lut[s_offset + (data[0] as usize * PDM_DECIMATION as usize / 8 + 3) as usize]
+ lut[s_offset + (data[7] as usize * PDM_DECIMATION as usize / 8 + 4) as usize]
+ lut[s_offset + (data[6] as usize * PDM_DECIMATION as usize / 8 + 5) as usize]
+ lut[s_offset + (data[5] as usize * PDM_DECIMATION as usize / 8 + 6) as usize]
+ lut[s_offset + (data[4] as usize * PDM_DECIMATION as usize / 8 + 7) as usize];
return lut[s_offset + (data[3] as usize * PDM_DECIMATION as usize / 8)]
+ lut[s_offset + (data[2] as usize * PDM_DECIMATION as usize / 8 + 1)]
+ lut[s_offset + (data[1] as usize * PDM_DECIMATION as usize / 8 + 2)]
+ lut[s_offset + (data[0] as usize * PDM_DECIMATION as usize / 8 + 3)]
+ lut[s_offset + (data[7] as usize * PDM_DECIMATION as usize / 8 + 4)]
+ lut[s_offset + (data[6] as usize * PDM_DECIMATION as usize / 8 + 5)]
+ lut[s_offset + (data[5] as usize * PDM_DECIMATION as usize / 8 + 6)]
+ lut[s_offset + (data[4] as usize * PDM_DECIMATION as usize / 8 + 7)];
}
fn convolve(
signal: &[u16],
Expand Down

0 comments on commit ee4c5d7

Please sign in to comment.