Files
Ravi ReddyandClaude Opus 5.5 3b371cdb28 Add VoiceNotes firmware and CDM customer service SQL project
VoiceNotes is an Arduino sketch for the Waveshare ESP32-C6-LCD-0.85 that
records meetings and voice memos to microSD and turns them into notes:

- Records 16 kHz mono WAV (up to 4 h) from the ES7210 dual mics, with a
  boosted preamp and soft-limited digital gain
- Transcribes via an OpenAI-compatible speech-to-text API in ~10 min parts
  cut at quiet points, with retries and resume after failures
- Summarizes the transcript with Claude into meeting notes (decisions,
  action items, topics with timestamps), streamed to and from the card
- Copies the notes to Nextcloud over WebDAV
- Shows recording/processing state on the 0.85" LCD and the LED ring
- Works around the board's SD card failing multi-sector reads

Credentials live in VoiceNotes/secrets.h, which is git-ignored; see
secrets.example.h.

Also adds the Microsoft CDM customer service SQL implementation (DDL,
sample data, reporting queries and docs). Its README is renamed to
CDM_README.md so the repository README stays at the top level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:22:10 +05:30

47 lines
1.7 KiB
C

// State shared between the main loop, the audio task and the network task.
#pragma once
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
enum AppState : uint8_t {
ST_BOOT,
ST_NO_SD,
ST_IDLE,
ST_RECORDING,
ST_SAVED,
ST_UPLOADING, // sending the WAV to the speech-to-text service
ST_TRANSCRIBING, // waiting for / receiving the transcript
ST_SUMMARIZING, // Claude is writing the notes
ST_SYNCING, // copying the notes to Nextcloud
ST_DONE,
ST_ERROR,
};
struct AppStatus {
volatile AppState state = ST_BOOT;
volatile uint32_t stateSince = 0; // millis() when the state was entered
volatile uint8_t progress = 0; // 0-100 for ST_UPLOADING
volatile uint32_t received = 0; // bytes of transcript / summary received
volatile float micLevel = 0; // 0..1, updated by the audio task
volatile uint32_t recordedBytes = 0; // PCM bytes in the current recording
volatile uint32_t droppedBytes = 0; // audio lost because the SD card stalled
volatile uint32_t maxSeconds = 0; // recording limit, from config and free space
volatile uint8_t partIndex = 0; // transcription part being processed (1-based)
volatile uint8_t partCount = 0; // estimated number of parts
char lastRecording[64] = ""; // full path of the newest .wav
char detail[96] = ""; // file name / error text shown on screen
};
extern AppStatus app;
// The LCD and the microSD share one SPI bus; anything touching either must hold this.
extern SemaphoreHandle_t spiMutex;
struct SpiLock {
SpiLock() { xSemaphoreTake(spiMutex, portMAX_DELAY); }
~SpiLock() { xSemaphoreGive(spiMutex); }
};
void setState(AppState s, const char *detail = nullptr);
bool timeIsValid();