===== HELPER: Start async playback task =====
| 391 | |
| 392 | // ===== HELPER: Start async playback task ===== |
| 393 | static bool startAsyncPlayback( |
| 394 | AudioGenerator *generator, AudioFileSource *source, AudioOutputI2S *output, const String &filename |
| 395 | ) { |
| 396 | initAudioPlayer(); |
| 397 | |
| 398 | if (!g_audioPlayer->lock(pdMS_TO_TICKS(1000))) { |
| 399 | Serial.println("ERROR: Could not acquire lock for async playback"); |
| 400 | delete generator; |
| 401 | delete source; |
| 402 | delete output; |
| 403 | _setup_codec_speaker(false); |
| 404 | return false; |
| 405 | } |
| 406 | |
| 407 | // Set up state |
| 408 | g_audioPlayer->generator = generator; |
| 409 | g_audioPlayer->source = source; |
| 410 | g_audioPlayer->output = output; |
| 411 | g_audioPlayer->state = PLAYBACK_PLAYING; |
| 412 | g_audioPlayer->mode = PLAYBACK_ASYNC; |
| 413 | g_audioPlayer->currentFile = filename; |
| 414 | g_audioPlayer->stopRequested = false; |
| 415 | g_audioPlayer->pauseRequested = false; |
| 416 | g_audioPlayer->volumeChanged = false; |
| 417 | g_audioPlayer->currentGain = bruceConfig.soundVolume / AUDIO_VOLUME_MAX; // Store initial gain |
| 418 | g_audioPlayer->startTime = millis(); |
| 419 | g_audioPlayer->pausedTime = 0; |
| 420 | g_audioPlayer->totalPausedDuration = 0; |
| 421 | |
| 422 | g_audioPlayer->unlock(); |
| 423 | |
| 424 | // Create task |
| 425 | BaseType_t result = xTaskCreatePinnedToCore( |
| 426 | audioPlaybackTask, |
| 427 | "AudioPlayback", |
| 428 | AUDIO_TASK_STACK_SIZE, |
| 429 | NULL, |
| 430 | AUDIO_TASK_PRIORITY, |
| 431 | &g_audioPlayer->taskHandle, |
| 432 | AUDIO_TASK_CORE |
| 433 | ); |
| 434 | |
| 435 | if (result != pdPASS || !g_audioPlayer->taskHandle) { |
| 436 | Serial.println("ERROR: Failed to create playback task"); |
| 437 | |
| 438 | // Cleanup on failure |
| 439 | if (g_audioPlayer->lock(pdMS_TO_TICKS(500))) { |
| 440 | g_audioPlayer->cleanup(); |
| 441 | g_audioPlayer->state = PLAYBACK_IDLE; |
| 442 | g_audioPlayer->taskHandle = nullptr; |
| 443 | g_audioPlayer->unlock(); |
| 444 | } |
| 445 | |
| 446 | _setup_codec_speaker(false); |
| 447 | return false; |
| 448 | } |
| 449 | |
| 450 | return true; |
no test coverage detected