rtsp_conn.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "rtsp_conn.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include "audio_receiver.h"
  6. #include "ptp_clock.h"
  7. #include "settings.h"
  8. rtsp_conn_t *rtsp_conn_create(void) {
  9. rtsp_conn_t *conn = calloc(1, sizeof(rtsp_conn_t));
  10. if (!conn) {
  11. return NULL;
  12. }
  13. // Load saved volume or use default
  14. float saved_volume;
  15. if (settings_get_volume(&saved_volume) == ESP_OK) {
  16. conn->volume_db = saved_volume;
  17. // Apply volume curve
  18. if (saved_volume <= -30.0f) {
  19. conn->volume_q15 = 0;
  20. } else if (saved_volume >= 0.0f) {
  21. conn->volume_q15 = 32768;
  22. } else {
  23. float normalized = (saved_volume + 30.0f) / 30.0f;
  24. conn->volume_q15 = (int32_t)(normalized * normalized * 32768.0f);
  25. }
  26. } else {
  27. conn->volume_db = -15.0f; // Half volume (midpoint of -30..0 dB range)
  28. float normalized = (conn->volume_db + 30.0f) / 30.0f;
  29. conn->volume_q15 = (int32_t)(normalized * normalized * 32768.0f);
  30. }
  31. conn->data_socket = -1;
  32. conn->control_socket = -1;
  33. conn->event_socket = -1;
  34. return conn;
  35. }
  36. void rtsp_conn_free(rtsp_conn_t *conn) {
  37. if (!conn) {
  38. return;
  39. }
  40. // Persist volume at disconnect
  41. settings_persist_volume();
  42. // Cleanup any resources
  43. rtsp_conn_cleanup(conn);
  44. // Free HAP session if present
  45. if (conn->hap_session) {
  46. hap_session_free(conn->hap_session);
  47. conn->hap_session = NULL;
  48. }
  49. free(conn);
  50. }
  51. void rtsp_conn_reset_stream(rtsp_conn_t *conn) {
  52. if (!conn) {
  53. return;
  54. }
  55. // Reset stream state but keep session alive
  56. conn->stream_active = false;
  57. conn->stream_paused = true; // Paused, not fully torn down
  58. // Keep ports allocated for quick resume
  59. // Don't clear: data_port, control_port, timing_port, event_port
  60. }
  61. void rtsp_conn_cleanup(rtsp_conn_t *conn) {
  62. if (!conn) {
  63. return;
  64. }
  65. // Note: audio_receiver_stop() is NOT called here — it is a global operation
  66. // and must be managed by the caller (rtsp_server cleanup / handle_teardown)
  67. // to avoid killing a new session's audio during client replacement.
  68. // Close sockets
  69. if (conn->data_socket >= 0) {
  70. close(conn->data_socket);
  71. conn->data_socket = -1;
  72. }
  73. if (conn->control_socket >= 0) {
  74. close(conn->control_socket);
  75. conn->control_socket = -1;
  76. }
  77. if (conn->event_socket >= 0) {
  78. close(conn->event_socket);
  79. conn->event_socket = -1;
  80. }
  81. // Reset stream state
  82. conn->stream_active = false;
  83. conn->stream_paused = false;
  84. conn->data_port = 0;
  85. conn->control_port = 0;
  86. conn->timing_port = 0;
  87. conn->event_port = 0;
  88. conn->buffered_port = 0;
  89. // Clear PTP clock for fresh sync on next connection
  90. ptp_clock_clear();
  91. // Reset encryption state
  92. conn->encrypted_mode = false;
  93. }
  94. void rtsp_conn_set_volume(rtsp_conn_t *conn, float volume_db) {
  95. if (!conn) {
  96. return;
  97. }
  98. conn->volume_db = volume_db;
  99. // AirPlay volume: 0 dB = max, -30 dB = mute
  100. // Use squared curve for better perceptual control
  101. if (volume_db <= -30.0f) {
  102. conn->volume_q15 = 0;
  103. } else if (volume_db >= 0.0f) {
  104. conn->volume_q15 = 32768;
  105. } else {
  106. // Map -30..0 to 0..1, then square for perceptual curve
  107. float normalized = (volume_db + 30.0f) / 30.0f;
  108. float curved = normalized * normalized;
  109. conn->volume_q15 = (int32_t)(curved * 32768.0f);
  110. }
  111. // Update cached volume + DAC (NVS persisted at disconnect)
  112. settings_set_volume(volume_db);
  113. }
  114. int32_t rtsp_conn_get_volume_q15(rtsp_conn_t *conn) {
  115. if (!conn) {
  116. return 32768; // Default full volume
  117. }
  118. return conn->volume_q15;
  119. }