#ifndef NIGHTAIR_SNORE_H #define NIGHTAIR_SNORE_H #include #ifdef __cplusplus extern "C" { #endif #if defined(__GNUC__) || defined(__clang__) #define NA_API __attribute__((visibility("default"))) #else #define NA_API #endif #define NA_SDK_ABI_VERSION 1 typedef struct na_session na_session; typedef enum na_status { NA_OK = 0, NA_INVALID_ARGUMENT = 1, NA_INVALID_STATE = 2, NA_READ_ERROR = 3, NA_OUT_OF_MEMORY = 4, NA_ANALYSIS_ERROR = 5, NA_LIMIT_EXCEEDED = 6 } na_status; /* A replayable mono PCM source. offset_frames is relative to the current part. Fill requested_frames (or a positive short read), and return the number written. Requests contain at most 16,384 frames. Zero/negative means read failed. Return identical samples on replay. Values must be finite in [-1,1]. The SDK synchronously borrows context only during na_session_add_part. */ typedef int32_t (*na_read_pcm)(void *context, int64_t offset_frames, float *out_mono, int32_t requested_frames); typedef struct na_summary { double recorded_seconds; /* Sum of submitted part durations. */ double detected_sound_seconds; /* Final periodic-gated model evidence. */ double episode_seconds; /* Includes observed gaps up to 8 s. */ double clip_eligible_seconds; /* Subset of detected sound evidence. */ uint32_t event_count; /* Contiguous runs of detected sound. */ uint32_t episode_count; } na_summary; typedef struct na_event { double start_seconds; /* Timeline coordinates, half-open [start,end). */ double end_seconds; float peak_score; /* Highest raw generated-model output in this run. */ } na_event; NA_API const char *na_sdk_version(void); NA_API const char *na_model_version(void); NA_API const char *na_configuration_id(void); NA_API const char *na_status_message(na_status status); /* Use one serial owner per session. Different sessions may run concurrently. Create sets *out to NULL on failure. Destroy accepts NULL. */ NA_API na_status na_session_create(na_session **out); NA_API void na_session_destroy(na_session *session); /* Add a completed physical part in chronological order. Supply its original recording boundary because the C frontend normalizes each part as a unit. Use a fixed mono rate in 8000..48000 Hz. The reduced ratio sample_rate:16000 must have both terms <=4096 (e.g., 8000, 11025, 16000, 22050, 44100, 48000). A part needs >=2 source frames and <=INT_MAX resampled 16 kHz frames. Timeline end is limited to INT_MAX seconds to retain sub-microsecond precision. Call on a worker thread. Do not re-enter or destroy a session during its read callback. The start_frame coordinate is relative to the session origin. Gaps are excluded from recorded duration and break events and periodicity. Parts must not overlap. A failed add leaves the session's committed evidence intact for retry. */ NA_API na_status na_session_add_part(na_session *session, uint32_t sample_rate, int64_t start_frame, int64_t frame_count, na_read_pcm read, void *context); /* Convenience for one contiguous, resident mono part; no ownership transfer. */ NA_API na_status na_session_add_pcm(na_session *session, uint32_t sample_rate, int64_t start_frame, const float *mono, int64_t frame_count); /* Finish requires at least one successfully submitted part. Repeated finish returns the same summary. Read events in [0, event_count) after finish. */ NA_API na_status na_session_finish(na_session *session, na_summary *out); NA_API na_status na_session_event(const na_session *session, uint32_t index, na_event *out); #ifdef __cplusplus } #endif #endif