ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
c6_cam_audio.c File Reference

Interrupt-driven onboard PDM microphone recorder for camera servers. More...

#include <stdint.h>
#include <string.h>
#include "c6_camera_server.h"
#include "ra8_attributes.h"
#include "ra8_audio.h"
#include "ra8_audio_source_pdm.h"
#include "ra8_board_ek_ra8d2.h"
#include "ra8_err.h"
#include "ra8_register_guard.h"
Include dependency graph for c6_cam_audio.c:

Go to the source code of this file.

Data Structures

struct  c6_cam_audio_bank_t
 Writer position and timing metadata for one SDRAM audio bank. More...

Enumerations

enum  c6_cam_audio_cfg_t : uint32_t {
  k_c6_cam_audio_rate_hz = 16000U ,
  k_c6_cam_audio_frame_samples = 256U ,
  k_c6_cam_audio_ring_samples = 16000U ,
  k_c6_cam_audio_settle_ms = 300U ,
  k_c6_cam_audio_discard = 1024U ,
  k_c6_cam_audio_poll_attempts = 500000U ,
  k_c6_cam_audio_irq_priority = 5U ,
  k_c6_cam_audio_bank_count = 2U ,
  k_c6_cam_audio_gain = 16U ,
  k_c6_cam_wav_header_bytes = 44U ,
  k_c6_cam_wav_sample_bytes = 2U ,
  k_c6_cam_wav_capacity ,
  k_c6_cam_byte_mask = 0xFFU ,
  k_c6_cam_shift_24 = 24U ,
  k_c6_cam_ms_per_second = 1000U ,
  k_c6_cam_wav_riff_overhead = 36U ,
  k_c6_cam_wav_audio_format_off = 20U ,
  k_c6_cam_wav_channels_off = 22U ,
  k_c6_cam_wav_byte_rate_off = 28U ,
  k_c6_cam_wav_bits_off = 34U ,
  k_c6_cam_wav_data_size_off = 40U
}
 Audio capture, storage, and WAV constants. More...

Functions

static void internal_c6_cam_audio_put_u16 (uint8_t *out, uint16_t value)
 Write one little-endian 16-bit scalar.
static void internal_c6_cam_audio_put_u32 (uint8_t *out, uint32_t value)
 Write one little-endian 32-bit scalar.
static int16_t internal_c6_cam_audio_s16 (int32_t sample)
 Convert signed 20-bit PDM PCM to saturated signed 16-bit PCM.
static void internal_c6_cam_audio_on_frame (void *ctx, const ra8_audio_frame_t *frame)
 Append one complete audio frame to the active SDRAM ring.
static void internal_c6_cam_audio_write_header (uint32_t samples)
 Serialize the canonical mono PCM-S16LE WAV header.
ra8_err_t c6_cam_audio_start (void)
 Start continuous MIC1 capture into the SDRAM audio ring.
ra8_err_t c6_cam_audio_snapshot_wav (const uint8_t **out_wav, uint32_t *out_bytes, uint32_t *out_timestamp_ms)
 Snapshot the rolling microphone ring as mono PCM-S16LE WAV.

Variables

static ra8_audio_source_t s_audio_source
 Fixed audio source objects and interrupt assembly scratch.
static ra8_audio_source_pdm_state_t s_audio_state
static int32_t s_audio_frame [k_c6_cam_audio_frame_samples]
static int32_t s_audio_ring [k_c6_cam_audio_bank_count][k_c6_cam_audio_ring_samples]
 Ping-pong PCM rings and generated WAV live in external SDRAM.
static uint8_t s_audio_wav [k_c6_cam_wav_capacity]
static volatile uint8_t s_audio_active_bank
 Active ISR bank and per-bank metadata guarded during handoff.
static c6_cam_audio_bank_t s_audio_banks [k_c6_cam_audio_bank_count]
static const uint8_t s_wav_tag_riff [] = {'R', 'I', 'F', 'F'}
 The three fixed-width chunk tags of a canonical PCM WAV header.
static const uint8_t s_wav_tag_wavefmt [] = {'W', 'A', 'V', 'E', 'f', 'm', 't', ' '}
static const uint8_t s_wav_tag_data [] = {'d', 'a', 't', 'a'}

Detailed Description

Interrupt-driven onboard PDM microphone recorder for camera servers.

Tag
[Ring 6 / APP] {World: S}

The PDM-IF hardware continuously decimates MIC1 into 20-bit PCM. The generic ra8_audio PDM backend assembles fixed frames in interrupt context, then this module appends them to a caller-owned one-second SDRAM bank. HTTP requests atomically hand capture to the other SDRAM bank and expose the stable bank as PCM-S16LE WAV without stopping the PDM source, camera capture, or allocating memory.

Since
0.1.0

Definition in file c6_cam_audio.c.

Enumeration Type Documentation

◆ c6_cam_audio_cfg_t

enum c6_cam_audio_cfg_t : uint32_t

Audio capture, storage, and WAV constants.

Enumerator
k_c6_cam_audio_rate_hz 

Mono PCM sample rate.

k_c6_cam_audio_frame_samples 

Samples assembled per IRQ frame.

k_c6_cam_audio_ring_samples 

One-second rolling sample window.

k_c6_cam_audio_settle_ms 

Microphone/filter settling delay.

k_c6_cam_audio_discard 

Startup transient samples.

k_c6_cam_audio_poll_attempts 

Initialization polling bound.

k_c6_cam_audio_irq_priority 

PDM FIFO NVIC priority.

k_c6_cam_audio_bank_count 

Ping-pong SDRAM capture banks.

k_c6_cam_audio_gain 

WAV digital gain before scaling.

k_c6_cam_wav_header_bytes 

Canonical PCM WAV header size.

k_c6_cam_wav_sample_bytes 

PCM-S16LE bytes per mono sample.

k_c6_cam_wav_capacity 

Complete WAV capacity.

k_c6_cam_byte_mask 

One serialized byte mask.

k_c6_cam_shift_24 

Most-significant byte shift.

k_c6_cam_ms_per_second 

Milliseconds per second.

k_c6_cam_wav_riff_overhead 

RIFF size excluding 8-byte lead.

k_c6_cam_wav_audio_format_off 

WAV audio-format field offset.

k_c6_cam_wav_channels_off 

WAV channel-count field offset.

k_c6_cam_wav_byte_rate_off 

WAV byte-rate field offset.

k_c6_cam_wav_bits_off 

WAV bits-per-sample field offset.

k_c6_cam_wav_data_size_off 

WAV data-size field offset.

Definition at line 32 of file c6_cam_audio.c.

Function Documentation

◆ c6_cam_audio_snapshot_wav()

ra8_err_t c6_cam_audio_snapshot_wav ( const uint8_t ** out_wav,
uint32_t * out_bytes,
uint32_t * out_timestamp_ms )
nodiscard

◆ c6_cam_audio_start()

◆ internal_c6_cam_audio_on_frame()

void internal_c6_cam_audio_on_frame ( void * ctx,
const ra8_audio_frame_t * frame )
static

Append one complete audio frame to the active SDRAM ring.

Writes interrupt-delivered PCM into the selected bank and updates bounded metadata.

Parameters
[in,out]ctxUnused callback context.
[in]frameBorrowed PCM-S32LE audio frame.
Precondition
frame is null or remains valid for the callback duration.
The active bank index selects one of the two static banks.
Postcondition
Valid samples are appended with circular wraparound.
Metadata describes retained count, next write index, and oldest timestamp.
Note
This callback runs in the PDM interrupt path.
Since
0.1.0

Definition at line 170 of file c6_cam_audio.c.

References ra8_audio_frame_t::data, ra8_audio_frame_t::format, k_c6_cam_audio_rate_hz, k_c6_cam_audio_ring_samples, k_c6_cam_ms_per_second, k_ra8_audio_format_pcm_s32le, c6_cam_audio_bank_t::oldest_timestamp_ms, RA8_INTERNAL, s_audio_active_bank, s_audio_banks, s_audio_ring, c6_cam_audio_bank_t::sample_count, ra8_audio_frame_t::sample_count, ra8_audio_frame_t::timestamp_ms, and c6_cam_audio_bank_t::write_index.

Referenced by c6_cam_audio_start().

◆ internal_c6_cam_audio_put_u16()

void internal_c6_cam_audio_put_u16 ( uint8_t * out,
uint16_t value )
static

Write one little-endian 16-bit scalar.

Splits the value into two wire-order WAV bytes.

Parameters
[out]outDestination for two bytes.
[in]valueScalar to serialize.
Precondition
out addresses at least two writable bytes.
No concurrent writer modifies the same destination bytes.
Postcondition
out[0] contains the least-significant byte.
out[1] contains the most-significant byte.
Note
The helper performs no alignment-dependent stores.
Since
0.1.0

Definition at line 105 of file c6_cam_audio.c.

References k_c6_cam_byte_mask, and RA8_INTERNAL.

Referenced by c6_cam_audio_snapshot_wav(), and internal_c6_cam_audio_write_header().

◆ internal_c6_cam_audio_put_u32()

void internal_c6_cam_audio_put_u32 ( uint8_t * out,
uint32_t value )
static

Write one little-endian 32-bit scalar.

Splits the value into four wire-order WAV bytes.

Parameters
[out]outDestination for four bytes.
[in]valueScalar to serialize.
Precondition
out addresses at least four writable bytes.
No concurrent writer modifies the same destination bytes.
Postcondition
Destination bytes contain value in little-endian order.
No byte beyond the four-byte destination span is modified.
Note
The helper performs no alignment-dependent stores.
Since
0.1.0

Definition at line 123 of file c6_cam_audio.c.

References k_c6_cam_byte_mask, k_c6_cam_shift_24, and RA8_INTERNAL.

Referenced by internal_c6_cam_audio_write_header().

◆ internal_c6_cam_audio_s16()

int16_t internal_c6_cam_audio_s16 ( int32_t sample)
static

Convert signed 20-bit PDM PCM to saturated signed 16-bit PCM.

Applies fixed application gain, removes four low-significance bits, then saturates to the WAV range.

Parameters
[in]sampleSigned sample supplied by the PDM backend.
Returns
Converted PCM sample.
Return values
INT16_MAXThe scaled input exceeded positive 16-bit range.
INT16_MINThe scaled input exceeded negative 16-bit range.
Precondition
sample is a sign-extended PDM sample or another valid signed integer.
No mutable audio state is required.
Postcondition
The result lies in the signed 16-bit range.
Global ring and WAV storage remain unchanged.
Note
Integer division intentionally discards four low bits.
Since
0.1.0

Definition at line 146 of file c6_cam_audio.c.

References k_c6_cam_audio_gain, and RA8_INTERNAL.

Referenced by c6_cam_audio_snapshot_wav().

◆ internal_c6_cam_audio_write_header()

void internal_c6_cam_audio_write_header ( uint32_t samples)
static

Serialize the canonical mono PCM-S16LE WAV header.

Writes RIFF, format, rate, alignment, and data-size fields into static storage.

Parameters
[in]samplesNumber of mono samples following the header.
Precondition
samples does not exceed the configured ring capacity.
s_audio_wav is not concurrently served while the snapshot is built.
Postcondition
The first 44 bytes contain a self-consistent PCM-S16LE WAV header.
Payload bytes after the header remain unchanged.
Note
The sample rate is fixed at 16 kHz mono.
Since
0.1.0

Definition at line 210 of file c6_cam_audio.c.

References internal_c6_cam_audio_put_u16(), internal_c6_cam_audio_put_u32(), k_c6_cam_audio_rate_hz, k_c6_cam_wav_audio_format_off, k_c6_cam_wav_bits_off, k_c6_cam_wav_byte_rate_off, k_c6_cam_wav_channels_off, k_c6_cam_wav_data_size_off, k_c6_cam_wav_riff_overhead, k_c6_cam_wav_sample_bytes, memcpy(), RA8_INTERNAL, s_audio_wav, s_wav_tag_data, s_wav_tag_riff, and s_wav_tag_wavefmt.

Referenced by c6_cam_audio_snapshot_wav().

Variable Documentation

◆ s_audio_active_bank

volatile uint8_t s_audio_active_bank
static

Active ISR bank and per-bank metadata guarded during handoff.

Definition at line 77 of file c6_cam_audio.c.

Referenced by c6_cam_audio_snapshot_wav(), and internal_c6_cam_audio_on_frame().

◆ s_audio_banks

◆ s_audio_frame

int32_t s_audio_frame[k_c6_cam_audio_frame_samples]
static

Definition at line 68 of file c6_cam_audio.c.

Referenced by c6_cam_audio_start().

◆ s_audio_ring

Ping-pong PCM rings and generated WAV live in external SDRAM.

Definition at line 73 of file c6_cam_audio.c.

Referenced by c6_cam_audio_snapshot_wav(), and internal_c6_cam_audio_on_frame().

◆ s_audio_source

ra8_audio_source_t s_audio_source
static

Fixed audio source objects and interrupt assembly scratch.

Definition at line 66 of file c6_cam_audio.c.

Referenced by c6_cam_audio_start().

◆ s_audio_state

ra8_audio_source_pdm_state_t s_audio_state
static

Definition at line 67 of file c6_cam_audio.c.

Referenced by c6_cam_audio_start().

◆ s_audio_wav

uint8_t s_audio_wav[k_c6_cam_wav_capacity]
static

Definition at line 74 of file c6_cam_audio.c.

Referenced by c6_cam_audio_snapshot_wav(), and internal_c6_cam_audio_write_header().

◆ s_wav_tag_data

const uint8_t s_wav_tag_data[] = {'d', 'a', 't', 'a'}
static

Definition at line 91 of file c6_cam_audio.c.

Referenced by internal_c6_cam_audio_write_header().

◆ s_wav_tag_riff

const uint8_t s_wav_tag_riff[] = {'R', 'I', 'F', 'F'}
static

The three fixed-width chunk tags of a canonical PCM WAV header.

Byte arrays rather than C strings, because that is what the file format is: each tag is followed immediately by a binary length or format field, so the header carries no terminator after any of them and copying one would corrupt the field that follows.

Note
Read-only; only internal_c6_cam_audio_write_header copies them.
Since
0.1.0

Definition at line 89 of file c6_cam_audio.c.

Referenced by internal_c6_cam_audio_write_header().

◆ s_wav_tag_wavefmt

const uint8_t s_wav_tag_wavefmt[] = {'W', 'A', 'V', 'E', 'f', 'm', 't', ' '}
static

Definition at line 90 of file c6_cam_audio.c.

Referenced by internal_c6_cam_audio_write_header().