|
28 | 28 | #include "esp_gmf_io.h" |
29 | 29 | #include "esp_gmf_io_embed_flash.h" |
30 | 30 |
|
31 | | -static const char *TAG = "PLAYER_TEST"; |
32 | | - |
33 | 31 | #define PIPELINE_BLOCK_BIT BIT(0) |
34 | 32 |
|
| 33 | +// 定义事件组标志位 |
| 34 | +#define STATE_RUNNING_BIT (1 << 0) |
| 35 | +#define STATE_STOPPED_BIT (1 << 1) |
| 36 | +#define STATE_PAUSED_BIT (1 << 2) |
| 37 | +#define STATE_FINISHED_BIT (1 << 3) |
| 38 | +#define CUSTOM_HIGH_PRIO_TASK_STOP_BIT (1 << 4) |
| 39 | +#define CUSTOM_LOW_PRIO_TASK_STOP_BIT (1 << 5) |
| 40 | + |
| 41 | +typedef struct { |
| 42 | + esp_asp_handle_t *player_handle; |
| 43 | + volatile bool *test_flag; |
| 44 | + EventGroupHandle_t state_event_group; |
| 45 | +} test_task_params_t; |
| 46 | + |
| 47 | +static const char *TAG = "PLAYER_TEST"; |
| 48 | + |
35 | 49 | static const char *dec_file_path[] = { |
36 | 50 | "file://sdcard/test.mp3", |
37 | 51 | "file://sdcard/test.opus", |
@@ -605,3 +619,180 @@ TEST_CASE("Play, Multiple-file Async Playing", "[Simple_Player][leaks=14000]") |
605 | 619 | vTaskDelay(1000 / portTICK_PERIOD_MS); |
606 | 620 | ESP_GMF_MEM_SHOW(TAG); |
607 | 621 | } |
| 622 | + |
| 623 | +static int test_event_callback(esp_asp_event_pkt_t *event, void *ctx) |
| 624 | +{ |
| 625 | + if (event->type == ESP_ASP_EVENT_TYPE_MUSIC_INFO) { |
| 626 | + esp_asp_music_info_t info = {0}; |
| 627 | + memcpy(&info, event->payload, event->payload_size); |
| 628 | + ESP_LOGW(TAG, "Get info, rate:%d, channels:%d, bits:%d", info.sample_rate, info.channels, info.bits); |
| 629 | + } else if (event->type == ESP_ASP_EVENT_TYPE_STATE) { |
| 630 | + esp_asp_state_t st = 0; |
| 631 | + memcpy(&st, event->payload, event->payload_size); |
| 632 | + ESP_LOGW(TAG, "Get State, %d,%s", st, esp_audio_simple_player_state_to_str(st)); |
| 633 | + |
| 634 | + uint8_t bits = 0; |
| 635 | + switch (st) { |
| 636 | + case ESP_ASP_STATE_RUNNING: |
| 637 | + bits = STATE_RUNNING_BIT; |
| 638 | + break; |
| 639 | + case ESP_ASP_STATE_STOPPED: |
| 640 | + bits = STATE_STOPPED_BIT; |
| 641 | + break; |
| 642 | + case ESP_ASP_STATE_PAUSED: |
| 643 | + bits = STATE_PAUSED_BIT; |
| 644 | + break; |
| 645 | + case ESP_ASP_STATE_FINISHED: |
| 646 | + bits = STATE_FINISHED_BIT; |
| 647 | + break; |
| 648 | + default: |
| 649 | + break; |
| 650 | + } |
| 651 | + if (bits != 0) { |
| 652 | + // Set event group bits |
| 653 | + xEventGroupSetBits((EventGroupHandle_t)ctx, bits); |
| 654 | + } |
| 655 | + } |
| 656 | + return 0; |
| 657 | +} |
| 658 | + |
| 659 | +// Low priority task:run simple player and randomly pause or stop it |
| 660 | +void low_priority_task(void *pvParameters) |
| 661 | +{ |
| 662 | + ESP_LOGI(TAG, "Low priority task running ..."); |
| 663 | + srand(xTaskGetTickCount() ^ (uint32_t)pvParameters); |
| 664 | + |
| 665 | + test_task_params_t *task_params = (test_task_params_t *)pvParameters; |
| 666 | + esp_asp_handle_t *handle = task_params->player_handle; |
| 667 | + EventGroupHandle_t event_group = task_params->state_event_group; |
| 668 | + |
| 669 | + esp_asp_state_t state; |
| 670 | + esp_gmf_err_t err; |
| 671 | + |
| 672 | + err = esp_audio_simple_player_run(*handle, "file://sdcard/alarm_44100hz_16bit_2ch_100ms.mp3", NULL); |
| 673 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 674 | + |
| 675 | + while (*(task_params->test_flag)) { |
| 676 | + vTaskDelay(pdMS_TO_TICKS(90 + rand() % 40)); |
| 677 | + |
| 678 | + err = esp_audio_simple_player_get_state(*handle, &state); |
| 679 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 680 | + |
| 681 | + if (state == ESP_ASP_STATE_RUNNING) { |
| 682 | + uint8_t op = rand() % 2; |
| 683 | + switch (op) { |
| 684 | + case 0: // Pause |
| 685 | + ESP_LOGW(TAG, "Player is running, trying to PAUSE it"); |
| 686 | + err = esp_audio_simple_player_pause(*handle); |
| 687 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 688 | + break; |
| 689 | + |
| 690 | + case 1: // Stop |
| 691 | + ESP_LOGW(TAG, "Player is running, trying to STOP it"); |
| 692 | + err = esp_audio_simple_player_stop(*handle); |
| 693 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 694 | + break; |
| 695 | + } |
| 696 | + } |
| 697 | + } |
| 698 | + |
| 699 | + ESP_LOGI(TAG, "Low priority task is done"); |
| 700 | + xEventGroupSetBits(event_group, CUSTOM_LOW_PRIO_TASK_STOP_BIT); |
| 701 | + vTaskDelete(NULL); |
| 702 | +} |
| 703 | + |
| 704 | +// High priority task:monitor player state and recover it if needed |
| 705 | +void high_priority_task(void *pvParameters) |
| 706 | +{ |
| 707 | + ESP_LOGI(TAG, "High priority task running ..."); |
| 708 | + |
| 709 | + test_task_params_t *task_params = (test_task_params_t *)pvParameters; |
| 710 | + esp_asp_handle_t *handle = task_params->player_handle; |
| 711 | + EventGroupHandle_t event_group = task_params->state_event_group; |
| 712 | + |
| 713 | + EventBits_t bits; |
| 714 | + TickType_t wait_timeout = 100; |
| 715 | + |
| 716 | + while (*(task_params->test_flag)) { |
| 717 | + bits = xEventGroupWaitBits(event_group, |
| 718 | + STATE_STOPPED_BIT | STATE_FINISHED_BIT | STATE_PAUSED_BIT, |
| 719 | + pdTRUE, pdFALSE, portMAX_DELAY); |
| 720 | + |
| 721 | + if ((bits & STATE_FINISHED_BIT) || (bits & STATE_STOPPED_BIT)) { |
| 722 | + wait_timeout = 200; |
| 723 | + xEventGroupClearBits(event_group, STATE_FINISHED_BIT | STATE_STOPPED_BIT | STATE_RUNNING_BIT); |
| 724 | + ESP_LOGW(TAG, "Player FINISHED or STOPPED, high priority begin to recover player"); |
| 725 | + esp_gmf_err_t err = esp_audio_simple_player_run(*handle, "file://sdcard/alarm_44100hz_16bit_2ch_100ms.mp3", NULL); |
| 726 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 727 | + } else if (bits & STATE_PAUSED_BIT) { |
| 728 | + wait_timeout = 100; |
| 729 | + xEventGroupClearBits(event_group, STATE_PAUSED_BIT | STATE_RUNNING_BIT); |
| 730 | + ESP_LOGW(TAG, "Player PAUSED, high priority begin to recover player"); |
| 731 | + esp_gmf_err_t err = esp_audio_simple_player_resume(*handle); |
| 732 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 733 | + } |
| 734 | + |
| 735 | + EventBits_t run_bits = xEventGroupWaitBits(event_group, |
| 736 | + STATE_RUNNING_BIT, |
| 737 | + pdTRUE, pdFALSE, |
| 738 | + pdMS_TO_TICKS(wait_timeout)); |
| 739 | + TEST_ASSERT_TRUE(run_bits & STATE_RUNNING_BIT); |
| 740 | + } |
| 741 | + |
| 742 | + ESP_LOGI(TAG, "High priority task is done"); |
| 743 | + xEventGroupSetBits(event_group, CUSTOM_HIGH_PRIO_TASK_STOP_BIT); |
| 744 | + vTaskDelete(NULL); |
| 745 | +} |
| 746 | + |
| 747 | +TEST_CASE("Pause, Stop, and Run APIs for Multi-task Execution", "[Simple_Player]") |
| 748 | +{ |
| 749 | + esp_log_level_set("*", ESP_LOG_INFO); |
| 750 | + ESP_GMF_MEM_SHOW(TAG); |
| 751 | + esp_gmf_app_setup_codec_dev(NULL); |
| 752 | + void *sdcard_handle = NULL; |
| 753 | + esp_gmf_app_setup_sdcard(&sdcard_handle); |
| 754 | + |
| 755 | + esp_asp_cfg_t cfg = { |
| 756 | + .in.cb = NULL, |
| 757 | + .in.user_ctx = NULL, |
| 758 | + .out.cb = out_data_callback, |
| 759 | + .out.user_ctx = esp_gmf_app_get_playback_handle(), |
| 760 | + .task_prio = 5, |
| 761 | + }; |
| 762 | + |
| 763 | + esp_asp_handle_t handle = NULL; |
| 764 | + esp_gmf_err_t err = esp_audio_simple_player_new(&cfg, &handle); |
| 765 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 766 | + |
| 767 | + EventGroupHandle_t event_group = xEventGroupCreate(); |
| 768 | + xEventGroupClearBits(event_group, 0xFFFFFF); |
| 769 | + err = esp_audio_simple_player_set_event(handle, test_event_callback, event_group); |
| 770 | + |
| 771 | + test_task_params_t *params = malloc(sizeof(test_task_params_t)); |
| 772 | + volatile bool test_flag = true; |
| 773 | + |
| 774 | + params->player_handle = &handle; |
| 775 | + params->test_flag = &test_flag; |
| 776 | + params->state_event_group = event_group; |
| 777 | + |
| 778 | + xTaskCreate(high_priority_task, "High Priority Task", 4096, (void *)params, 7, NULL); |
| 779 | + xTaskCreate(low_priority_task, "Low Priority Task", 4096, (void *)params, 6, NULL); |
| 780 | + |
| 781 | + vTaskDelay(pdMS_TO_TICKS(20000)); |
| 782 | + test_flag = false; |
| 783 | + |
| 784 | + xEventGroupWaitBits(event_group, |
| 785 | + CUSTOM_HIGH_PRIO_TASK_STOP_BIT | CUSTOM_LOW_PRIO_TASK_STOP_BIT, |
| 786 | + pdTRUE, pdTRUE, |
| 787 | + portMAX_DELAY); |
| 788 | + ESP_LOGI(TAG, "All tasks are deleted, test finished"); |
| 789 | + err = esp_audio_simple_player_stop(handle); |
| 790 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 791 | + err = esp_audio_simple_player_destroy(handle); |
| 792 | + TEST_ASSERT_EQUAL(ESP_OK, err); |
| 793 | + esp_gmf_app_teardown_sdcard(sdcard_handle); |
| 794 | + esp_gmf_app_teardown_codec_dev(); |
| 795 | + vTaskDelay(1000 / portTICK_PERIOD_MS); |
| 796 | + free(params); |
| 797 | + ESP_GMF_MEM_SHOW(TAG); |
| 798 | +} |
0 commit comments