158 lines
5.2 KiB
C
158 lines
5.2 KiB
C
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
|
|
/************************************************************************************
|
|
** **
|
|
** mcHF QRP Transceiver **
|
|
** K Atanassov - M0NKA 2014 **
|
|
** **
|
|
**---------------------------------------------------------------------------------**
|
|
** **
|
|
** File name: **
|
|
** Description: **
|
|
** Last Modified: **
|
|
** Licence: GNU GPLv3 **
|
|
************************************************************************************/
|
|
|
|
// Credits - SDR cube!!!
|
|
|
|
// Common
|
|
#include "uhsdr_board.h"
|
|
#include "dds_table.h"
|
|
#include "softdds.h"
|
|
|
|
|
|
// Two Tone Dds
|
|
soft_dds_t dbldds[2];
|
|
|
|
uint32_t softdds_stepForSampleRate(float32_t freq, uint32_t samp_rate)
|
|
{
|
|
uint64_t freq64_shifted = freq * DDS_TBL_SIZE;
|
|
freq64_shifted <<= SOFTDDS_ACC_SHIFT;
|
|
uint64_t step = freq64_shifted / samp_rate;
|
|
return step;
|
|
}
|
|
|
|
/**
|
|
* Initialize softdds for given frequency and sample rate
|
|
*/
|
|
void softdds_setFreqDDS(soft_dds_t* softdds_p, float32_t freq, uint32_t samp_rate,uint8_t smooth)
|
|
{
|
|
// Reset accumulator, if need smooth tone
|
|
// transition, do not reset it (e.g. wspr)
|
|
if(smooth == false)
|
|
{
|
|
softdds_p->acc = 0;
|
|
}
|
|
// Calculate new step
|
|
softdds_p->step = softdds_stepForSampleRate(freq,samp_rate);
|
|
}
|
|
|
|
|
|
/**
|
|
* Initialize softdds for given frequency and sample rate
|
|
*/
|
|
|
|
void softdds_configRunIQ(float freq[2],uint32_t samp_rate,uint8_t smooth)
|
|
{
|
|
softdds_setFreqDDS(&dbldds[0],freq[0],samp_rate,smooth);
|
|
softdds_setFreqDDS(&dbldds[1],freq[1],samp_rate,smooth);
|
|
}
|
|
|
|
void softdds_genIQSingleTone(soft_dds_t* dds, float32_t *i_buff,float32_t *q_buff,uint16_t size)
|
|
{
|
|
for(uint16_t i = 0; i < size; i++)
|
|
{
|
|
// Calculate next sample
|
|
uint32_t k = softdds_nextSampleIndex(dds);
|
|
|
|
// Load I value (sin)
|
|
*i_buff = DDS_TABLE[k];
|
|
|
|
// -90 degrees shift (cos)
|
|
// Load Q value
|
|
*q_buff = DDS_TABLE[softdds_phase_shift90(k)];
|
|
|
|
// Next ptr
|
|
i_buff++;
|
|
q_buff++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Generates the addition of two sinus frequencies as IQ data stream
|
|
* min/max value is +/-2^15-1
|
|
* Frequencies need to be configured using softdds_setfreq_dbl
|
|
*/
|
|
void softdds_genIQTwoTone(soft_dds_t* ddsA, soft_dds_t* ddsB, float *i_buff,float *q_buff,ushort size)
|
|
{
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
uint32_t k[2];
|
|
// Calculate next sample
|
|
k[0] = softdds_nextSampleIndex(ddsA);
|
|
k[1] = softdds_nextSampleIndex(ddsB);
|
|
|
|
// Load I value 0.5*(sin(a)+sin(b))
|
|
*i_buff = ((int32_t)DDS_TABLE[k[0]] + (int32_t)DDS_TABLE[k[1]])/2;
|
|
|
|
*q_buff = ((int32_t)DDS_TABLE[softdds_phase_shift90(k[0])] + (int32_t)DDS_TABLE[softdds_phase_shift90(k[1])])/2;
|
|
|
|
// Next ptr
|
|
i_buff++;
|
|
q_buff++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Overlays an audio stream with a beep signal
|
|
* @param dds The previously initialized dds configuration
|
|
* @param buffer audio buffer of blockSize (mono/single channel) samples
|
|
* @param blockSize
|
|
* @param scaling scale the resulting sine wave with this factor
|
|
*/
|
|
|
|
void softdds_addSingleTone(soft_dds_t* dds_ptr, float32_t* buffer, const size_t blockSize, float32_t scaling)
|
|
{
|
|
for(int i=0; i < blockSize; i++) // transfer to DMA buffer and do conversion to INT
|
|
{
|
|
buffer[i] += (float32_t)softdds_nextSample(dds_ptr) * scaling; // load indexed sine wave value, adding it to audio, scaling the amplitude and putting it on "b" - speaker (ONLY)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Overlays an audio stream with a beep signal
|
|
* @param dds The previously initialized dds configuration
|
|
* @param buffer1 audio buffer of blockSize (mono/single channel) samples
|
|
* @param buffer2 audio buffer of blockSize (mono/single channel) samples
|
|
* @param blockSize
|
|
* @param scaling scale the resulting sine wave with this factor
|
|
*/
|
|
|
|
void softdds_addSingleToneToTwobuffers(soft_dds_t* dds_ptr, float32_t* buffer1, float32_t* buffer2, const size_t blockSize, float32_t scaling)
|
|
{
|
|
float32_t Tone;
|
|
for(int i=0; i < blockSize; i++) // transfer to DMA buffer and do conversion to INT
|
|
{
|
|
Tone=(float32_t) softdds_nextSample(dds_ptr) * scaling; // load indexed sine wave value, adding it to audio, scaling the amplitude and putting it on "b" - speaker (ONLY)
|
|
buffer1[i] += Tone;
|
|
buffer2[i] += Tone;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Generates the sinus frequencies as IQ data stream
|
|
* min/max value is +/-2^15-1
|
|
* Frequency needs to be configured using softdds_setfreq
|
|
*/
|
|
void softdds_runIQ(float32_t *i_buff,float32_t *q_buff,uint16_t size)
|
|
{
|
|
if (dbldds[1].step>0.0)
|
|
{
|
|
softdds_genIQTwoTone(&dbldds[0], &dbldds[1], i_buff, q_buff,size);
|
|
}
|
|
else
|
|
{
|
|
softdds_genIQSingleTone(&dbldds[0],i_buff,q_buff,size);
|
|
}
|
|
}
|
|
|