main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include "FreeRTOS.h"
  7. #include "hardware/clocks.h"
  8. #include "pico/cyw43_arch.h"
  9. #include "pico/multicore.h"
  10. #include "pico/stdlib.h"
  11. #include "task.h"
  12. #include "hardware/dma.h"
  13. #include "pcm-g711/pcm-g711/g711.h"
  14. #include "peer.h"
  15. #include "rp2040_i2s_example/i2s.h"
  16. static __attribute__((aligned(8))) pio_i2s i2s;
  17. #define TEST_TASK_PRIORITY (tskIDLE_PRIORITY + 1UL)
  18. TaskHandle_t xPcTaskHandle;
  19. PeerConnection* g_pc;
  20. PeerConnectionState eState = PEER_CONNECTION_CLOSED;
  21. int gDataChannelOpened = 0;
  22. static void oniceconnectionstatechange(PeerConnectionState state, void* user_data) {
  23. eState = state;
  24. printf("state = %d\n", state);
  25. }
  26. static void onmessage(char* msg, size_t len, void* userdata, uint16_t sid) {
  27. if (strncmp(msg, "ping", 4) == 0) {
  28. printf("Got ping, send pong\n");
  29. peer_connection_datachannel_send(g_pc, "pong", 4);
  30. }
  31. }
  32. void onopen(void* userdata) {
  33. gDataChannelOpened = 1;
  34. }
  35. static void onclose(void* userdata) {
  36. }
  37. #if 1
  38. uint32_t get_epoch_time() {
  39. struct timeval tv;
  40. gettimeofday(&tv, NULL);
  41. return (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
  42. }
  43. #endif
  44. static void dma_i2s_in_handler(void) {
  45. int8_t alaw[AUDIO_BUFFER_FRAMES];
  46. int16_t pcm[AUDIO_BUFFER_FRAMES];
  47. int32_t* input_buffer;
  48. if (*(int32_t**)dma_hw->ch[i2s.dma_ch_in_ctrl].read_addr == i2s.input_buffer) {
  49. input_buffer = i2s.input_buffer;
  50. } else {
  51. input_buffer = i2s.input_buffer + STEREO_BUFFER_SIZE;
  52. }
  53. for (int i = 0; i < AUDIO_BUFFER_FRAMES; i++) {
  54. pcm[i] = (int16_t)(input_buffer[2 * i + 1] >> 16);
  55. alaw[i] = ALaw_Encode(pcm[i]);
  56. }
  57. #if 1
  58. static uint32_t total_bytes = 0;
  59. static uint32_t last_time = 0;
  60. total_bytes += AUDIO_BUFFER_FRAMES;
  61. uint32_t current_time = get_epoch_time();
  62. if (current_time - last_time > 1000) {
  63. printf("AUDIO_BUFFER_FRAMES: %d, bps: %d\n", AUDIO_BUFFER_FRAMES, 1000 * total_bytes * 8 / (current_time - last_time));
  64. total_bytes = 0;
  65. last_time = current_time;
  66. }
  67. #endif
  68. if (eState == PEER_CONNECTION_COMPLETED) {
  69. peer_connection_send_audio(g_pc, alaw, AUDIO_BUFFER_FRAMES);
  70. }
  71. dma_hw->ints0 = 1u << i2s.dma_ch_in_data; // clear the IRQ
  72. }
  73. void peer_connection_task() {
  74. printf("Run peer connection task on the core: %d\n", portGET_CORE_ID());
  75. while (1) {
  76. peer_connection_loop(g_pc);
  77. vTaskDelay(pdMS_TO_TICKS(1));
  78. }
  79. }
  80. void main_task(__unused void* params) {
  81. if (cyw43_arch_init()) {
  82. printf("failed to initialise\n");
  83. vTaskDelete(NULL);
  84. }
  85. cyw43_arch_enable_sta_mode();
  86. printf("Connecting to Wi-Fi...\n");
  87. while (1) {
  88. if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 100000)) {
  89. printf("failed to connect.\n");
  90. vTaskDelay(1000);
  91. } else {
  92. printf("Connected.\n");
  93. break;
  94. }
  95. }
  96. PeerConfiguration config = {
  97. .ice_servers = {
  98. {.urls = "stun:stun.l.google.com:19302"}},
  99. .audio_codec = CODEC_PCMA,
  100. .datachannel = DATA_CHANNEL_STRING,
  101. };
  102. peer_init();
  103. g_pc = peer_connection_create(&config);
  104. peer_connection_oniceconnectionstatechange(g_pc, oniceconnectionstatechange);
  105. peer_connection_ondatachannel(g_pc, onmessage, onopen, onclose);
  106. ServiceConfiguration service_config = SERVICE_CONFIG_DEFAULT();
  107. service_config.client_id = "mypico";
  108. service_config.pc = g_pc;
  109. peer_signaling_set_config(&service_config);
  110. peer_signaling_join_channel();
  111. xTaskCreate(peer_connection_task, "PeerConnectionTask", 4096, NULL, TEST_TASK_PRIORITY, &xPcTaskHandle);
  112. i2s_program_start_synched(pio0, &i2s_config_default, dma_i2s_in_handler, &i2s);
  113. printf("Run main task on the core: %d\n", portGET_CORE_ID());
  114. printf("open https://sepfy.github.io/webrtc?deviceId=mypico\n");
  115. while (true) {
  116. peer_signaling_loop();
  117. vTaskDelay(pdMS_TO_TICKS(10));
  118. }
  119. cyw43_arch_deinit();
  120. }
  121. void vLaunch(void) {
  122. TaskHandle_t task;
  123. xTaskCreate(main_task, "TestMainThread", 4096, NULL, TEST_TASK_PRIORITY, &task);
  124. vTaskCoreAffinitySet(task, 1);
  125. vTaskStartScheduler();
  126. }
  127. int main(void) {
  128. stdio_init_all();
  129. // set_sys_clock_khz(132000, true);
  130. vLaunch();
  131. return 0;
  132. }