afsk_demod.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #pragma once
  2. #include <vector>
  3. #include <deque>
  4. #include <string>
  5. #include <memory>
  6. #include <optional>
  7. #include <cmath>
  8. #include "wifi_configuration_ap.h"
  9. #include "application.h"
  10. // Audio signal processing constants for WiFi configuration via audio
  11. const size_t kAudioSampleRate = 6400;
  12. const size_t kMarkFrequency = 1800;
  13. const size_t kSpaceFrequency = 1500;
  14. const size_t kBitRate = 100;
  15. const size_t kWindowSize = 64;
  16. namespace audio_wifi_config
  17. {
  18. // Main function to receive WiFi credentials through audio signal
  19. void ReceiveWifiCredentialsFromAudio(Application *app, WifiConfigurationAp *wifi_ap);
  20. /**
  21. * Goertzel algorithm implementation for single frequency detection
  22. * Used to detect specific audio frequencies in the AFSK demodulation process
  23. */
  24. class FrequencyDetector
  25. {
  26. private:
  27. float frequency_; // Target frequency (normalized, i.e., f / fs)
  28. size_t window_size_; // Window size for analysis
  29. float frequency_bin_; // Frequency bin
  30. float angular_frequency_; // Angular frequency
  31. float cos_coefficient_; // cos(w)
  32. float sin_coefficient_; // sin(w)
  33. float filter_coefficient_; // 2 * cos(w)
  34. std::deque<float> state_buffer_; // Circular buffer for storing S[-1] and S[-2]
  35. public:
  36. /**
  37. * Constructor
  38. * @param frequency Normalized frequency (f / fs)
  39. * @param window_size Window size for analysis
  40. */
  41. FrequencyDetector(float frequency, size_t window_size);
  42. /**
  43. * Reset the detector state
  44. */
  45. void Reset();
  46. /**
  47. * Process one audio sample
  48. * @param sample Input audio sample
  49. */
  50. void ProcessSample(float sample);
  51. /**
  52. * Calculate current amplitude
  53. * @return Amplitude value
  54. */
  55. float GetAmplitude() const;
  56. };
  57. /**
  58. * Audio signal processor for Mark/Space frequency pair detection
  59. * Processes audio signals to extract digital data using AFSK demodulation
  60. */
  61. class AudioSignalProcessor
  62. {
  63. private:
  64. std::deque<float> input_buffer_; // Input sample buffer
  65. size_t input_buffer_size_; // Input buffer size = window size
  66. size_t output_sample_count_; // Output sample counter
  67. size_t samples_per_bit_; // Samples per bit threshold
  68. std::unique_ptr<FrequencyDetector> mark_detector_; // Mark frequency detector
  69. std::unique_ptr<FrequencyDetector> space_detector_; // Space frequency detector
  70. public:
  71. /**
  72. * Constructor
  73. * @param sample_rate Audio sampling rate
  74. * @param mark_frequency Mark frequency for digital '1'
  75. * @param space_frequency Space frequency for digital '0'
  76. * @param bit_rate Data transmission bit rate
  77. * @param window_size Analysis window size
  78. */
  79. AudioSignalProcessor(size_t sample_rate, size_t mark_frequency, size_t space_frequency,
  80. size_t bit_rate, size_t window_size);
  81. /**
  82. * Process input audio samples
  83. * @param samples Input audio sample vector
  84. * @return Vector of Mark probability values (0.0 to 1.0)
  85. */
  86. std::vector<float> ProcessAudioSamples(const std::vector<float> &samples);
  87. };
  88. /**
  89. * Data reception state machine states
  90. */
  91. enum class DataReceptionState
  92. {
  93. kInactive, // Waiting for start signal
  94. kWaiting, // Detected potential start, waiting for confirmation
  95. kReceiving // Actively receiving data
  96. };
  97. /**
  98. * Data buffer for managing audio-to-digital data conversion
  99. * Handles the complete process from audio signal to decoded text data
  100. */
  101. class AudioDataBuffer
  102. {
  103. private:
  104. DataReceptionState current_state_; // Current reception state
  105. std::deque<uint8_t> identifier_buffer_; // Buffer for start/end identifier detection
  106. size_t identifier_buffer_size_; // Identifier buffer size
  107. std::vector<uint8_t> bit_buffer_; // Buffer for storing bit stream
  108. size_t max_bit_buffer_size_; // Maximum bit buffer size
  109. const std::vector<uint8_t> start_of_transmission_; // Start-of-transmission identifier
  110. const std::vector<uint8_t> end_of_transmission_; // End-of-transmission identifier
  111. bool enable_checksum_validation_; // Whether to validate checksum
  112. public:
  113. std::optional<std::string> decoded_text; // Successfully decoded text data
  114. /**
  115. * Default constructor using predefined start and end identifiers
  116. */
  117. AudioDataBuffer();
  118. /**
  119. * Constructor with custom parameters
  120. * @param max_byte_size Expected maximum data size in bytes
  121. * @param start_identifier Start-of-transmission identifier
  122. * @param end_identifier End-of-transmission identifier
  123. * @param enable_checksum Whether to enable checksum validation
  124. */
  125. AudioDataBuffer(size_t max_byte_size, const std::vector<uint8_t> &start_identifier,
  126. const std::vector<uint8_t> &end_identifier, bool enable_checksum = false);
  127. /**
  128. * Process probability data and attempt to decode
  129. * @param probabilities Vector of Mark probabilities
  130. * @param threshold Decision threshold for bit detection
  131. * @return true if complete data was successfully received and decoded
  132. */
  133. bool ProcessProbabilityData(const std::vector<float> &probabilities, float threshold = 0.5f);
  134. /**
  135. * Calculate checksum for ASCII text
  136. * @param text Input text string
  137. * @return Checksum value (0-255)
  138. */
  139. static uint8_t CalculateChecksum(const std::string &text);
  140. private:
  141. /**
  142. * Convert bit vector to byte vector
  143. * @param bits Input bit vector
  144. * @return Converted byte vector
  145. */
  146. std::vector<uint8_t> ConvertBitsToBytes(const std::vector<uint8_t> &bits) const;
  147. /**
  148. * Clear all buffers and reset state
  149. */
  150. void ClearBuffers();
  151. };
  152. // Default start and end transmission identifiers
  153. extern const std::vector<uint8_t> kDefaultStartTransmissionPattern;
  154. extern const std::vector<uint8_t> kDefaultEndTransmissionPattern;
  155. }