diff options
Diffstat (limited to 'src/fsm/psk31.c')
-rw-r--r-- | src/fsm/psk31.c | 194 |
1 files changed, 170 insertions, 24 deletions
diff --git a/src/fsm/psk31.c b/src/fsm/psk31.c index 6eafa53..a4e770a 100644 --- a/src/fsm/psk31.c +++ b/src/fsm/psk31.c @@ -53,12 +53,148 @@ * The psk31_fill_buffer() function can be called to fetch audio from the audio_queue */ -#define PSK31_MAX_MESSAGE_LEN 10240 +/* + * PSK31 Varicode + * http://aintel.bi.ehu.es/psk31.html + */ +const char *psk31_varicode[] = { // {{{ + "1010101011", + "1011011011", + "1011101101", + "1101110111", + "1011101011", + "1101011111", + "1011101111", + "1011111101", + "1011111111", + "11101111", + "11101", + "1101101111", + "1011011101", + "11111", + "1101110101", + "1110101011", + "1011110111", + "1011110101", + "1110101101", + "1110101111", + "1101011011", + "1101101011", + "1101101101", + "1101010111", + "1101111011", + "1101111101", + "1110110111", + "1101010101", + "1101011101", + "1110111011", + "1011111011", + "1101111111", + "1", + "111111111", + "101011111", + "111110101", + "111011011", + "1011010101", + "1010111011", + "101111111", + "11111011", + "11110111", + "101101111", + "111011111", + "1110101", + "110101", + "1010111", + "110101111", + "10110111", + "10111101", + "11101101", + "11111111", + "101110111", + "101011011", + "101101011", + "110101101", + "110101011", + "110110111", + "11110101", + "110111101", + "111101101", + "1010101", + "111010111", + "1010101111", + "1010111101", + "1111101", + "11101011", + "10101101", + "10110101", + "1110111", + "11011011", + "11111101", + "101010101", + "1111111", + "111111101", + "101111101", + "11010111", + "10111011", + "11011101", + "10101011", + "11010101", + "111011101", + "10101111", + "1101111", + "1101101", + "101010111", + "110110101", + "101011101", + "101110101", + "101111011", + "1010101101", + "111110111", + "111101111", + "111111011", + "1010111111", + "101101101", + "1011011111", + "1011", + "1011111", + "101111", + "101101", + "11", + "111101", + "1011011", + "101011", + "1101", + "111101011", + "10111111", + "11011", + "111011", + "1111", + "111", + "111111", + "110111111", + "10101", + "10111", + "101", + "110111", + "1111011", + "1101011", + "11011111", + "1011101", + "111010101", + "1010110111", + "110111011", + "1010110101", + "1011010111", + "1110110101", +}; //}}} + + +#define PSK31_MAX_MESSAGE_LEN 4096 #define PHASE_BUFFER_SIZE (20 + PSK31_MAX_MESSAGE_LEN + 20) struct psk31_out_message_s { - // Contains a sequence of ones and zeros corresponding to - // the BPSK31 phase + // Contains a string sequence of '0' and '1' corresponding to + // the BPSK31 phase. Is terminated with '\0' char phase_buffer[PHASE_BUFFER_SIZE]; size_t phase_buffer_end; @@ -75,7 +211,7 @@ static int psk31_samplerate; static int psk31_transmit_ongoing; static void psk31_task(void *pvParameters); -static void psk31_str_to_bits(const char* instr, char* outbits); +static int psk31_str_to_bits(const char* instr, char* outbits); void psk31_init(unsigned int samplerate) @@ -83,20 +219,20 @@ void psk31_init(unsigned int samplerate) psk31_samplerate = samplerate; psk31_transmit_ongoing = 0; - psk31_msg_queue = xQueueCreate(15, sizeof(struct psk31_out_message_s)); + psk31_msg_queue = xQueueCreate(1, sizeof(struct psk31_out_message_s)); if (psk31_msg_queue == 0) { while(1); /* fatal error */ } - psk31_audio_queue = xQueueCreate(2, AUDIO_BUF_LEN * sizeof(int16_t)); + psk31_audio_queue = xQueueCreate(1, AUDIO_BUF_LEN * sizeof(int16_t)); if (psk31_audio_queue == 0) { while(1); /* fatal error */ } xTaskCreate( psk31_task, - "TaskPSK31", - 8*configMINIMAL_STACK_SIZE, + "TaskPSK", + 5*configMINIMAL_STACK_SIZE, (void*) NULL, tskIDLE_PRIORITY + 2UL, NULL); @@ -112,7 +248,7 @@ int psk31_push_message(const char* text, int frequency) msg.phase_buffer_end = 0; msg.freq = frequency; - psk31_str_to_bits(text, msg.phase_buffer); + msg.phase_buffer_end = psk31_str_to_bits(text, msg.phase_buffer); xQueueSendToBack(psk31_msg_queue, &msg, portMAX_DELAY); @@ -120,16 +256,25 @@ int psk31_push_message(const char* text, int frequency) } // Write the waveform into the buffer (stereo) -size_t psk31_fill_buffer(int16_t *buf, size_t bufsize); +size_t psk31_fill_buffer(int16_t *buf, size_t bufsize) +{ + if (xQueueReceiveFromISR(psk31_audio_queue, buf, NULL)) { + return bufsize; + } + else { + return 0; + } +} -// Return 1 if the psk31 generator has completed transmission -int psk31_busy(void); +int psk31_busy(void) +{ + return psk31_transmit_ongoing; +} static int16_t psk31_audio_buf[AUDIO_BUF_LEN]; +static struct psk31_out_message_s psk31_fill_msg_current; static void psk31_task(void *pvParameters) { - struct psk31_out_message_s psk31_fill_msg_current; - float nco_phase = 0.0f; float ampl = 0.0f; @@ -141,6 +286,8 @@ static void psk31_task(void *pvParameters) psk31_transmit_ongoing = 1; + const float base_ampl = 20000.0f; + /* BPSK31 is at 31.25 symbols per second. */ const int samples_per_symbol = psk31_samplerate * 100 / 3125; @@ -148,20 +295,17 @@ static void psk31_task(void *pvParameters) const float omega = 2.0f * FLOAT_PI * psk31_fill_msg_current.freq / (float)psk31_samplerate; - int current_psk_phase = 0; + int current_psk_phase = 1; for (int i = 0; i < psk31_fill_msg_current.phase_buffer_end; i++) { for (int t = 0; t < samples_per_symbol; t++) { int16_t s = 0; - if (psk31_fill_msg_current.phase_buffer[i]) { - ampl = 32000.0f; + if (psk31_fill_msg_current.phase_buffer[i] == '1') { + ampl = base_ampl; } else { - ampl = - (float)current_psk_phase * - 32000.0f * - arm_cos_f32( + ampl = base_ampl * arm_cos_f32( FLOAT_PI*(float)t/(float)samples_per_symbol); } @@ -170,7 +314,8 @@ static void psk31_task(void *pvParameters) nco_phase -= 2.0f * FLOAT_PI; } - s = ampl * arm_sin_f32(nco_phase); + s = ampl * arm_sin_f32(nco_phase + + (current_psk_phase == 1 ? 0.0f : FLOAT_PI)); if (buf_pos == AUDIO_BUF_LEN) { xQueueSendToBack(psk31_audio_queue, &psk31_audio_buf, portMAX_DELAY); @@ -187,7 +332,7 @@ static void psk31_task(void *pvParameters) } - if (! psk31_fill_msg_current.phase_buffer[i]) { + if (psk31_fill_msg_current.phase_buffer[i] == '0') { current_psk_phase *= -1; } } @@ -206,7 +351,7 @@ static void psk31_task(void *pvParameters) * outstr must be at least size 20 + strlen(instr)*12 + 20 to accomodate * the header and tail */ -static void psk31_str_to_bits(const char* instr, char* outbits) +static int psk31_str_to_bits(const char* instr, char* outbits) { int i=0, j, k; @@ -232,6 +377,7 @@ static void psk31_str_to_bits(const char* instr, char* outbits) /* NULL terminate */ outbits[i] = 0; + return i; } #if 0 |