11package org.operatorfoundation.audiocoder
22
3- interface WSPRAudioSource {
3+ import org.operatorfoundation.audiocoder.models.WSPRAudioSourceStatus
4+ import org.operatorfoundation.audiocoder.WSPRConstants.WSPR_REQUIRED_BIT_DEPTH
5+ import org.operatorfoundation.audiocoder.WSPRConstants.WSPR_REQUIRED_CHANNELS
6+ import org.operatorfoundation.audiocoder.WSPRConstants.WSPR_REQUIRED_SAMPLE_RATE
7+
8+ /* *
9+ * Interface for providing audio data to WSPR station.
10+ *
11+ * Implementations must provide audio in the WSPR-required format:
12+ * - Sample rate: 12,000 Hz
13+ * - Bit depth: 16-bit signed integers
14+ * - Channels: Mono (single channel)
15+ * - Encoding: PCM (Pulse Code Modulation)
16+ *
17+ * The audio source should be designed for real-time operation and
18+ * handle buffering internally to provide smooth, continuous audio delivery.
19+ *
20+ * Example implementation:
21+ * class MyAudioSource : WSPRAudioSource {
22+ * override suspend fun initialize(): Result<Unit> {
23+ * // Set up audio hardware, open files, etc.
24+ * }
25+ *
26+ * override suspend fun readAudioChunk(durationMs: Long): ShortArray {
27+ * // Return audio samples for the requested duration
28+ * }
29+ * }
30+ */
31+ interface WSPRAudioSource
32+ {
33+ /* *
34+ * Initializes the audio source and prepares it for audio delivery.
35+ *
36+ * This method should:
37+ * - Configure audio hardware or open audio files
38+ * - Verify that the source can provide WSPR-compatible audio
39+ * - Set up any necessary buffering or processing pipelines
40+ * - Perform connectivity or permission checks
41+ *
42+ * The method should be idempotent - calling it multiple times should
43+ * not cause errors or resource leaks.
44+ *
45+ * @return Success if initialization completed without errors,
46+ * Failure with descriptive error information if initialization failed
47+ *
48+ * @throws WSPRAudioSourceException for unrecoverable initialization errors
49+ */
50+ suspend fun initialize (): Result <Unit >
51+
52+ /* *
53+ * Reads a chunk of audio data covering the specified time duration.
54+ *
55+ * This method provides audio samples in real-time for WSPR processing.
56+ * It should return approximately the number of samples corresponding
57+ * to the requested duration at 12kHz sample rate.
58+ *
59+ * Expected sample count calculation:
60+ * ```
61+ * sampleCount = (durationMs / 1000.0) * WSPR_SAMPLE_RATE_HZ
62+ * ```
63+ *
64+ * Behavior requirements:
65+ * - Returns audio promptly without excessive blocking
66+ * - Provides continuous audio stream (no gaps between calls)
67+ * - Handles timing variations gracefully
68+ * - Returns empty array if no audio is available
69+ *
70+ * @param durationMs Requested audio duration in milliseconds
71+ * @return Array of 16-bit audio samples covering the requested duration.
72+ * May be shorter than requested if insufficient audio is available.
73+ * Should not be longer than requested to prevent buffer overflow.
74+ *
75+ * @throws WSPRAudioSourceException for unrecoverable read errors
76+ */
77+ suspend fun readAudioChunk (durationMs : Long ): ShortArray
78+
79+ /* *
80+ * Releases all resources and stops audio acquisition.
81+ *
82+ * This method should:
83+ * - Stop any active audio recording or streaming
84+ * - Release hardware resources (USB connections, audio devices)
85+ * - Close open files or network connections
86+ * - Free memory buffers
87+ * - Cancel any background processing tasks
88+ *
89+ * After calling this method, the audio source should not be used
90+ * until initialize() is called again.
91+ *
92+ * The method should be safe to call multiple times and should not
93+ * throw exceptions even if cleanup encounters errors.
94+ */
95+ suspend fun cleanup ()
96+
97+ /* *
98+ * Gets current status and diagnostic information about the audio source.
99+ *
100+ * This method provides information useful for:
101+ * - Troubleshooting audio issues
102+ * - Monitoring source health and performance
103+ * - Displaying status in user interfaces
104+ *
105+ * @return Current status and diagnostic information
106+ */
107+ suspend fun getSourceStatus (): WSPRAudioSourceStatus
108+ }
109+
110+ /* *
111+ * Exception thrown by WSPR audio source implementations.
112+ */
113+ class WSPRAudioSourceException (
114+ message : String ,
115+ cause : Throwable ? = null
116+ ) : Exception(message, cause)
117+ {
118+ companion object
119+ {
120+ /* *
121+ * Creates an exception for initialization failures.
122+ *
123+ * @param sourceDescription Type or name of the audio source
124+ * @param cause Underlying cause of the failure
125+ * @return Formatted exception with descriptive message
126+ */
127+ fun createInitializationFailure (sourceDescription : String , cause : Throwable ? = null): WSPRAudioSourceException
128+ {
129+ return WSPRAudioSourceException (
130+ " Failed to initialize WSPR audio source: $sourceDescription . ${cause?.message ? : " Unknown error" } " ,
131+ cause
132+ )
133+ }
134+
135+ /* *
136+ * Creates an exception for audio reading failures.
137+ *
138+ * @param cause Underlying cause of the read failure
139+ * @return Formatted exception with descriptive message
140+ */
141+ fun createReadFailure (cause : Throwable ? = null): WSPRAudioSourceException
142+ {
143+ return WSPRAudioSourceException (
144+ " Failed to read audio data from WSPR source. ${cause?.message ? : " Unknown error" } " ,
145+ cause
146+ )
147+ }
148+
149+ /* *
150+ * Creates an exception for audio format compatibility issues.
151+ *
152+ * @param actualSampleRate Actual sample rate provided by source
153+ * @param actualChannels Actual channel count provided by source
154+ * @param actualBitDepth Actual bit depth provided by source
155+ * @return Formatted exception describing the compatibility issue
156+ */
157+ fun createFormatIncompatibility (
158+ actualSampleRate : Int ,
159+ actualChannels : Int ,
160+ actualBitDepth : Int
161+ ): WSPRAudioSourceException
162+ {
163+ return WSPRAudioSourceException (
164+ " Audio source format incompatible with WSPR requirements. " +
165+ " Required: ${WSPR_REQUIRED_SAMPLE_RATE } Hz, " +
166+ " ${WSPR_REQUIRED_CHANNELS } channel, " +
167+ " ${WSPR_REQUIRED_BIT_DEPTH } -bit. " +
168+ " Actual: ${actualSampleRate} Hz, ${actualChannels} channels, ${actualBitDepth} -bit."
169+ )
170+ }
171+ }
4172}
0 commit comments