|
| 1 | +import 'package:open_earable_protocols/open_earable_protocols.dart'; |
| 2 | + |
| 3 | +/// Receives progress updates for an audio buffer upload. |
| 4 | +typedef AudioResponseUploadProgressCallback = void Function( |
| 5 | + AudioResponseUploadProgress progress, |
| 6 | +); |
| 7 | + |
| 8 | +/// Current phase of an audio buffer upload. |
| 9 | +enum AudioResponseUploadPhase { |
| 10 | + /// The transfer is being initialized on the device. |
| 11 | + starting, |
| 12 | + |
| 13 | + /// Audio samples are being transferred and acknowledged by the device. |
| 14 | + uploading, |
| 15 | + |
| 16 | + /// All samples are acknowledged and the transfer is being committed. |
| 17 | + committing, |
| 18 | + |
| 19 | + /// The device successfully committed the transfer. |
| 20 | + completed, |
| 21 | +} |
| 22 | + |
| 23 | +/// Immutable progress reported while uploading an audio buffer. |
| 24 | +class AudioResponseUploadProgress { |
| 25 | + /// Creates an audio buffer upload progress update. |
| 26 | + const AudioResponseUploadProgress({ |
| 27 | + required this.phase, |
| 28 | + required this.acknowledgedSamples, |
| 29 | + required this.totalSamples, |
| 30 | + }); |
| 31 | + |
| 32 | + /// Current transfer phase. |
| 33 | + final AudioResponseUploadPhase phase; |
| 34 | + |
| 35 | + /// Number of samples acknowledged by the device. |
| 36 | + final int acknowledgedSamples; |
| 37 | + |
| 38 | + /// Total number of samples in the transfer. |
| 39 | + final int totalSamples; |
| 40 | + |
| 41 | + /// Fraction of samples acknowledged by the device, between zero and one. |
| 42 | + double get fraction => |
| 43 | + totalSamples == 0 ? 0 : acknowledgedSamples / totalSamples; |
| 44 | +} |
| 45 | + |
| 46 | +/// An interface for managing audio response measurements. |
| 47 | +abstract class AudioResponseManager { |
| 48 | + /// Uploads and commits signed 16-bit PCM [samples] for later measurements. |
| 49 | + /// |
| 50 | + /// [maximumSamplesPerChunk] must fit the effective GATT write payload. |
| 51 | + /// [onProgress] receives synchronous updates based on sample offsets |
| 52 | + /// acknowledged by the device. Exceptions thrown by the callback terminate |
| 53 | + /// the upload. |
| 54 | + Future<void> uploadAudioBuffer({ |
| 55 | + required int transferId, |
| 56 | + required List<int> samples, |
| 57 | + required int samplingRate, |
| 58 | + int maximumSamplesPerChunk = 118, |
| 59 | + AudioResponseUploadProgressCallback? onProgress, |
| 60 | + }); |
| 61 | + |
| 62 | + /// Starts a measurement and returns its protocol result. |
| 63 | + /// |
| 64 | + /// The [config] must reference a buffer previously committed by |
| 65 | + /// [uploadAudioBuffer]. |
| 66 | + Future<AudioResponseResult> measureAudioResponse(AudioResponseConfig config); |
| 67 | +} |
| 68 | + |
| 69 | +/// Error reported by the device while transferring an audio response buffer. |
| 70 | +class AudioResponseTransferException implements Exception { |
| 71 | + /// Creates an audio response transfer error from a protocol status value. |
| 72 | + const AudioResponseTransferException({ |
| 73 | + required this.status, |
| 74 | + required this.message, |
| 75 | + }); |
| 76 | + |
| 77 | + /// Numeric status reported by the audio response protocol. |
| 78 | + final int status; |
| 79 | + |
| 80 | + /// Human-readable description of [status]. |
| 81 | + final String message; |
| 82 | + |
| 83 | + @override |
| 84 | + String toString() => 'AudioResponseTransferException($status): $message'; |
| 85 | +} |
0 commit comments