Skip to content

Commit

Permalink
Ham: playback of pre-recorded weather/traffic/other advisory voice me…
Browse files Browse the repository at this point in the history
…ssage (WAV file) from micro-SD card into air with BOOT+PTT buttons press
  • Loading branch information
lyusupov committed Nov 27, 2023
1 parent bcdb3d0 commit 7320acb
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Data|FLARM NMEA|<p align="center">![](https://github.com/lyusupov/SoftRF/raw/mas
<sup>1</sup> - it is necessary for a reader to distinguish the difference between statement "**compatible**" and statement "**fully compatible**".<br>
&nbsp;&nbsp;&nbsp;&nbsp; SoftRF implements only a reasonable minimum of the protocols specs. No "bells and whistles" so far.<br>
<sup>2</sup> - FANET+ can not receive FLARM. However it is able to transmit it.<br>
<sup>3</sup> - valid for [**Prime Mark III**](https://github.com/lyusupov/SoftRF/wiki/Prime-Edition-MkIII) , [**Prime Mark II**](https://github.com/lyusupov/SoftRF/wiki/Prime-Edition-MkII) , [**Dongle**](https://github.com/lyusupov/SoftRF/wiki/Dongle-Edition) , [**Mini**](https://github.com/lyusupov/SoftRF/wiki/Mini-Edition) , [**Badge**](https://github.com/lyusupov/SoftRF/wiki/Badge-Edition) , [**Bracelet**](https://github.com/lyusupov/SoftRF/wiki/Bracelet-Edition) , [**Academy**](https://github.com/lyusupov/SoftRF/wiki/Academy-Edition) , [**Octave**](https://github.com/lyusupov/SoftRF/wiki/Octave-Concept) , [**Lego**](https://github.com/lyusupov/SoftRF/wiki/Lego-Edition) and [**Balkan**](https://github.com/lyusupov/SoftRF/wiki/Balkan-Edition) **Editions**; valid for [**Standalone**](https://github.com/lyusupov/SoftRF/wiki/Standalone-Edition) , [**UAV**](https://github.com/lyusupov/SoftRF/wiki/UAV-Edition) and [**Uni**](https://github.com/lyusupov/SoftRF/wiki/Uni-Edition) **Editions** with optional DIY [SoftRF LoRa RF module](https://github.com/lyusupov/SoftRF/wiki/SoftRF-LoRa-module)<br>
<sup>3</sup> - valid for [**Prime Mark III**](https://github.com/lyusupov/SoftRF/wiki/Prime-Edition-MkIII) , [**Prime Mark II**](https://github.com/lyusupov/SoftRF/wiki/Prime-Edition-MkII) , [**Dongle**](https://github.com/lyusupov/SoftRF/wiki/Dongle-Edition) , [**Mini**](https://github.com/lyusupov/SoftRF/wiki/Mini-Edition) , [**Badge**](https://github.com/lyusupov/SoftRF/wiki/Badge-Edition) , [**Bracelet**](https://github.com/lyusupov/SoftRF/wiki/Bracelet-Edition) , [**Academy**](https://github.com/lyusupov/SoftRF/wiki/Academy-Edition) , [**Octave**](https://github.com/lyusupov/SoftRF/wiki/Octave-Concept) , [**Lego**](https://github.com/lyusupov/SoftRF/wiki/Lego-Edition) , [**Balkan**](https://github.com/lyusupov/SoftRF/wiki/Balkan-Edition) and [**Midi**](https://github.com/lyusupov/SoftRF/wiki/Midi-Edition) **Editions**; valid for [**Standalone**](https://github.com/lyusupov/SoftRF/wiki/Standalone-Edition) , [**UAV**](https://github.com/lyusupov/SoftRF/wiki/UAV-Edition) and [**Uni**](https://github.com/lyusupov/SoftRF/wiki/Uni-Edition) **Editions** with optional DIY [SoftRF LoRa RF module](https://github.com/lyusupov/SoftRF/wiki/SoftRF-LoRa-module)<br>
<sup>4</sup> - [**Reception**](https://github.com/lyusupov/SoftRF/wiki/Uni-Edition#ads-b-out-remark) of traffic 'downlink' frames only. Valid for [**Uni Edition**](https://github.com/lyusupov/SoftRF/wiki/Uni-Edition) alone and for [**Standalone Edition**](https://github.com/lyusupov/SoftRF/wiki/Standalone-Edition) with optional DIY [SoftRF UAT module](https://github.com/lyusupov/UAT-test-signal#variant-2-advanced)<br>
<sup>5</sup> - Reception of traffic 'downlink' frames only. Valid for [**ES Edition**](https://github.com/lyusupov/SoftRF/wiki/ES-Edition)<br>
<sup>6</sup> - APRS is the only available with [**Ham Edition**](https://github.com/lyusupov/SoftRF/wiki/Ham-Edition)<br>
Expand Down
82 changes: 81 additions & 1 deletion software/firmware/source/SoftRF/src/platform/ESP32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,56 @@ extern SA818Controller controller;
extern uint32_t Data_Frequency;
extern uint32_t Voice_Frequency;
extern void sa868_Tx_LED_state(bool);

#if !defined(EXCLUDE_VOICE_MESSAGE)
#include <driver/i2s.h>
#include <AudioFileSourceSdFat.h>
#include <AudioGeneratorWAV.h>
#include <AudioOutputI2S.h>

#define MAX_FILENAME_LEN 64
#define WAV_FILE_PREFIX "/Audio/"
#define WAV_FILE_SUFFIX ".wav"

AudioGeneratorWAV *Audio_Gen;
AudioFileSourceSdFat *Audio_Source;
AudioOutputI2S *Audio_Sink;

bool playback_inited = false;

static bool play_file(char *filename)
{
bool rval = false;

if (Audio_Source->open(filename)) {
unsigned long Audio_Timemarker = millis();
Audio_Gen->begin(Audio_Source, Audio_Sink);

bool wdt_status = loopTaskWDTEnabled;

if (wdt_status) {
disableLoopWDT();
}

while (Audio_Gen->loop()) {
// feedLoopWDT();
if (millis() - Audio_Timemarker > 30000) {
Audio_Gen->stop();
Serial.println("ERROR: Audio timeout. Playback aborted.");
Serial.flush();
}
}

if (wdt_status) {
enableLoopWDT();
}

rval = true;
}

return rval;
}
#endif /* EXCLUDE_VOICE_MESSAGE */
#endif /* USE_SA8X8 */
#endif /* CONFIG_IDF_TARGET_ESP32S3 */

Expand Down Expand Up @@ -1140,6 +1190,23 @@ static void ESP32_setup()
digitalWrite(uSD_SS_pin, HIGH);

uSD_is_attached = uSD.cardBegin(SD_CONFIG);

#if !defined(EXCLUDE_VOICE_MESSAGE)
if (uSD_is_attached && uSD.card()->cardSize() > 0 && uSD.volumeBegin()) {
Audio_Gen = new AudioGeneratorWAV();
Audio_Source = new AudioFileSourceSdFat(uSD);

Audio_Sink = new AudioOutputI2S(0, AudioOutputI2S::INTERNAL_PDM);
Audio_Sink->SetPinout(I2S_PIN_NO_CHANGE,
I2S_PIN_NO_CHANGE,
SOC_GPIO_PIN_TWR2_PDM_OUT,
I2S_PIN_NO_CHANGE);
Audio_Sink->SetOutputModeMono(true);
Audio_Sink->SetChannels(1);
Audio_Sink->SetMclk(false);
playback_inited = true;
}
#endif /* EXCLUDE_VOICE_MESSAGE */
}
} else if (hw_info.model == SOFTRF_MODEL_MIDI) {

Expand Down Expand Up @@ -3823,7 +3890,11 @@ void handleMainEvent(AceButton* button, uint8_t eventType,
if (button == &button_ptt &&
Voice_Frequency > 0 &&
(settings->power_save & POWER_SAVE_NORECEIVE)) {
pinMode(SOC_GPIO_PIN_TWR2_MIC_CH_SEL, INPUT_PULLDOWN);
bool playback = false;
#if !defined(EXCLUDE_VOICE_MESSAGE)
playback = playback_inited && (digitalRead(SOC_GPIO_PIN_S3_BUTTON) == 0);
#endif /* EXCLUDE_VOICE_MESSAGE */
if (!playback) {pinMode(SOC_GPIO_PIN_TWR2_MIC_CH_SEL, INPUT_PULLDOWN);}
PTT_TxF = controller.getTXF();
controller.setTXF(Voice_Frequency / 1000000.0);
controller.update();
Expand All @@ -3844,6 +3915,15 @@ void handleMainEvent(AceButton* button, uint8_t eventType,
#endif /* USE_OLED */
sa868_Tx_LED_state(true);
controller.transmit();
#if !defined(EXCLUDE_VOICE_MESSAGE)
if (playback) {
char filename[MAX_FILENAME_LEN];
strcpy(filename, WAV_FILE_PREFIX);
strcat(filename, "message");
strcat(filename, WAV_FILE_SUFFIX);
play_file(filename);
}
#endif /* EXCLUDE_VOICE_MESSAGE */
}
break;
#endif /* USE_SA8X8 */
Expand Down
1 change: 1 addition & 0 deletions software/firmware/source/SoftRF/src/platform/ESP32.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ struct rst_info {
//#define USE_GDL90_MSL
#define USE_OGN_ENCRYPTION
#define ENABLE_PROL
#define EXCLUDE_VOICE_MESSAGE

//#define EXCLUDE_GNSS_UBLOX /* Neo-6/7/8, M10 */
#define ENABLE_UBLOX_RFS /* revert factory settings (when necessary) */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define SOC_GPIO_PIN_TWR2_RADIO_PD 40
#define SOC_GPIO_PIN_TWR2_RADIO_SQL 2 /* T-TWR 2.1 only */
#define SOC_GPIO_PIN_TWR2_MIC_CH_SEL 17
#define SOC_GPIO_PIN_TWR2_PDM_OUT 18

// Radio SPI (not in use)
#define SOC_GPIO_PIN_TWR2_MOSI 16
Expand Down

0 comments on commit 7320acb

Please sign in to comment.