kopia lustrzana https://github.com/kamocat/uSDX
SSB Tx Draft
The steps for single-sideband modulation are hashed out, but the actual sampling of audio is not implemented yetchibios
rodzic
55ad088791
commit
9c5011542d
|
@ -23,7 +23,7 @@ int32_t hilbert19(int16_t * src){
|
|||
return sum;
|
||||
}
|
||||
|
||||
int32_t hilbert32(int16_t * src, uint8_t i){
|
||||
int32_t diff32(int16_t * src, uint8_t i){
|
||||
i -= 16; // Move to the center of the history
|
||||
const uint8_t mask = 32-1;
|
||||
/* Hilbert coeffecients with a hamming window
|
||||
|
@ -42,3 +42,18 @@ int32_t hilbert32(int16_t * src, uint8_t i){
|
|||
sum += (src[(i-15)&mask]-src[(i+15)&mask]) * (int32_t)coef[7];
|
||||
return sum;
|
||||
}
|
||||
|
||||
int32_t hilbert32(int16_t * src, uint8_t i){
|
||||
i -= 16; // Move to the center of the history
|
||||
const uint8_t mask = 32-1;
|
||||
/* Differentiation coeffecients with a hamming window
|
||||
* Values are -1, 1/2, -1/3, 1/4, etc
|
||||
* Stored in 15.16 fixed-point
|
||||
*/
|
||||
const int16_t coef[] = {-4055,1967,-1245,868,-631,466,-344,252,-181,127,-86,57,-38,26,-22};
|
||||
int32_t sum = 0;
|
||||
for(uint8_t j = 0; j<15; ++i){
|
||||
sum += (src[(i-1-j)&mask]-src[(i+1+j)&mask]) * (int32_t)coef[j];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
|
|
@ -13,5 +13,15 @@ int32_t hilbert19(int16_t * src);
|
|||
* This implementation assumes a 32-element buffer, and wraps accordingly
|
||||
* @param src The source data. Make sure I and Q are not interlieved
|
||||
* @param i The index of the latest element. Older elements are assumed to have decreasing index.
|
||||
* @returns The input signal, delayed by 90 degrees (The imaginary component).
|
||||
*/
|
||||
int32_t hilbert32(int16_t * src, uint8_t i);
|
||||
|
||||
/** 31-element differentiation
|
||||
*
|
||||
* This implementation assumes a 32-element buffer, and wraps accordingly
|
||||
* @param src The source data. Make sure I and Q are not interlieved
|
||||
* @param i The index of the latest element. Older elements are assumed to have decreasing index.
|
||||
* @returns the derivative of the input
|
||||
*/
|
||||
int32_t diff32(int16_t * src, uint8_t i);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "ssb.h"
|
||||
#include "hilbert.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../trig.h"
|
||||
|
||||
msg_t ssb_rx(mailbox_t * inbox, enum radio_mode * mode){
|
||||
union complex c;
|
||||
|
@ -14,7 +15,7 @@ msg_t ssb_rx(mailbox_t * inbox, enum radio_mode * mode){
|
|||
int16_t real[len];
|
||||
int16_t imag[len];
|
||||
while((USB==*mode) || (LSB==*mode)){
|
||||
for( int i=0; i<len;){
|
||||
for( int i=0; i<len; ++i){
|
||||
/** Fetch new data */
|
||||
msg_t m = chMBFetchTimeout(inbox, &c.msg, TIME_MS2I(10));
|
||||
if(MSG_OK != m)
|
||||
|
@ -41,16 +42,36 @@ msg_t ssb_rx(mailbox_t * inbox, enum radio_mode * mode){
|
|||
return MSG_OK;
|
||||
}
|
||||
|
||||
const int32_t fscale = 1; //FIXME
|
||||
|
||||
void ssb_tx(int16_t * amp, int32_t * freq, int16_t * src, size_t qty){
|
||||
// Source data is single-channel audio
|
||||
int32_t f = freq[0];
|
||||
for(size_t i = 0; i < (qty-18); ++i){
|
||||
amp[i]=src[i+9];
|
||||
// FIXME: Subtraction is not a differentiator
|
||||
// Maybe the differentiation can be combined with the hilbert?
|
||||
f -= hilbert19(src+i) * fscale;
|
||||
freq[i]=f;
|
||||
msg_t ssb_tx(mailbox_t * inbox, enum radio_mode * mode, struct synth * txclk){
|
||||
union complex c;
|
||||
const int len = 32;
|
||||
const int sample_rate = 5000;
|
||||
int16_t raw[len];
|
||||
int16_t phase[len];
|
||||
while((USB==*mode) || (LSB==*mode)){
|
||||
for( int i=0; i<len; ++i){
|
||||
/** Fetch new data */
|
||||
msg_t m = chMBFetchTimeout(inbox, &c.msg, TIME_MS2I(10));
|
||||
if(MSG_OK != m)
|
||||
return m;
|
||||
raw[i] = c.real;
|
||||
/** Process the received data */
|
||||
int16_t imag = hilbert32(raw, i)>>16;
|
||||
if(LSB==*mode)
|
||||
imag=-imag;
|
||||
uint8_t j = (i-16)&31; // Match group delay of Hilbert transform
|
||||
int16_t real = raw[j]; //TODO: Match frequency response of Hilbert transform
|
||||
phase[i]=arctan3(imag, real);
|
||||
int16_t amp=magn(imag, real);
|
||||
int32_t freq = diff32(phase,i);
|
||||
freq *= sample_rate;
|
||||
/** Update the outputs
|
||||
* TODO: Fix amplitude based on frequency
|
||||
* TODO: Update DAC more frequently than si5351. Use DMA
|
||||
*/
|
||||
synthSetBaseband(txclk, freq);
|
||||
dacPutChannelX(&DACD1, 1, amp);
|
||||
}
|
||||
}
|
||||
return MSG_OK;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "rx.h"
|
||||
#include "../drivers/si5351.h"
|
||||
|
||||
/** Single sideband decoder
|
||||
*
|
||||
|
@ -16,4 +17,4 @@ msg_t ssb_rx(mailbox_t * inbox, enum radio_mode * mode);
|
|||
/** Singgle sideband encoder
|
||||
*
|
||||
*/
|
||||
void ssb_tx(int16_t * amp, int32_t * freq, int16_t * src, size_t qty);
|
||||
msg_t ssb_tx(mailbox_t * inbox, enum radio_mode * mode, struct synth * txclk);
|
||||
|
|
Ładowanie…
Reference in New Issue