sendAudioData method
Sends the currently buffered audio to one or more agent identities.
This is a one shot operation. Repeated calls are ignored after the buffer has been sent.
The stream is written to topic (default: dataTopic) and includes
attributes that help the agent interpret the raw audio payload.
Implementation
Future<void> sendAudioData({
required List<String> agents,
String topic = dataTopic,
}) async {
if (_isBufferSent) return;
if (agents.isEmpty) return;
final sampleRate = _renderedSampleRate;
final rawChannels = _renderedChannels ?? 1;
final channels = rawChannels > 0 ? rawChannels : 1;
if (sampleRate == null) {
logger.severe('[Preconnect audio] renderedSampleRate is null');
return;
}
if (rawChannels <= 0) {
logger.warning('[Preconnect audio] Invalid rendered channels: $rawChannels. Falling back to mono.');
}
// Wait for local track published event
final localTrackPublishedEvent = await _localTrackPublishedEvent;
logger.info('[Preconnect audio] localTrackPublishedEvent: $localTrackPublishedEvent');
final localTrackSid = localTrackPublishedEvent?.publication.track?.sid;
if (localTrackSid == null) {
logger.severe('[Preconnect audio] localTrackPublishedEvent is null');
return;
}
logger.info('[Preconnect audio] sending audio data to ${agents.map((e) => e).join(', ')} agent(s)');
final data = _buffer.takeBytes();
logger.info('[Preconnect audio] data.length: ${data.length}, bytes.length: ${_buffer.length}');
_isBufferSent = true;
final streamOptions = StreamBytesOptions(
topic: topic,
attributes: {
'sampleRate': sampleRate.toString(),
'channels': channels.toString(),
'commonFormat': 'int16',
'trackId': localTrackSid,
},
totalSize: data.length,
destinationIdentities: agents,
);
logger.info('[Preconnect audio] streamOptions: $streamOptions');
final writer = await _room.localParticipant!.streamBytes(streamOptions);
await writer.write(data);
await writer.close();
// Compute seconds of audio data sent
final int bytesPerSample = 2; // 16-bit audio
final int bytesPerFrame = bytesPerSample * channels;
final int totalFrames = data.length ~/ bytesPerFrame;
final double secondsOfAudio = totalFrames / sampleRate;
logger.info(
'[Preconnect audio] sent ${(data.length / 1024).toStringAsFixed(1)}KB of audio (${secondsOfAudio.toStringAsFixed(2)} seconds) to ${agents} agent(s)');
}