start method
Start the voice session Matches iOS VoiceSessionHandle.start()
Implementation
Future<void> start() async {
if (_isRunning) {
_logger.warning('Voice session already running');
return;
}
_logger.info('🚀 Starting voice session...');
// Check if voice agent components are ready
_logger.info('Checking if voice agent components are ready...');
final componentsReady = await _isVoiceAgentReadyCallback?.call() ?? false;
_logger.info('Voice agent components ready: $componentsReady');
if (!componentsReady) {
const errorMsg =
'Voice agent components not ready. Make sure STT, LLM, and TTS models are loaded.';
_logger.error('❌ $errorMsg');
_emit(const VoiceSessionError(message: errorMsg));
throw const VoiceSessionException(
VoiceSessionErrorType.notReady,
errorMsg,
);
}
// Always initialize voice agent with loaded models
// This creates the voice agent handle and connects it to the shared component handles
try {
_logger.info('Initializing voice agent with loaded models...');
await _initializeVoiceAgentCallback?.call();
_logger.info('✅ Voice agent initialized successfully');
} catch (e) {
_logger.error('❌ Failed to initialize voice agent: $e');
final errorMsg = 'Voice agent initialization failed: $e';
_emit(VoiceSessionError(message: errorMsg));
rethrow;
}
// Request mic permission via audio capture manager
_logger.info('Requesting microphone permission...');
final hasPermission = await _audioCapture.requestPermission();
if (!hasPermission) {
_logger.error('❌ Microphone permission denied');
_emit(const VoiceSessionError(message: 'Microphone permission denied'));
throw const VoiceSessionException(
VoiceSessionErrorType.microphonePermissionDenied,
'Microphone permission denied',
);
}
_logger.info('✅ Microphone permission granted');
_isRunning = true;
_emit(const VoiceSessionStarted());
// Start listening - this starts the audio capture loop
await _startListening();
_logger.info('✅ Voice session started with audio capture');
}