Compare commits

...

5 Commits

Author SHA1 Message Date
liuyihui 7b763a7da7 remove: sstv 2023-05-30 11:03:11 +08:00
liuyihui 085242a154 feat: ADC buffer count 2023-04-28 18:22:38 +08:00
liuyihui 824e73237b feat: 100us count, fft length, sample rate 2023-04-28 18:11:09 +08:00
liuyihui 50ee62911a feat: convert sound to image 2023-04-28 16:20:46 +08:00
liuyihui 109c1b74b0 style: macro location;
fix: hanning window width
2023-04-28 14:45:46 +08:00
18 changed files with 391 additions and 451 deletions

32
include/MMA8451Q.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include "derivative.h"
#define MMA8451Q_I2C_ADDRESS 0x1D
#define I2C_MWSR 0x00 /* Master write */
#define I2C_MRSW 0x01 /* Master read */
#define MMA8451Q_I2C_Start() I2C0->C1 |= 0x30;
#define MMA8451Q_I2C_Stop() I2C0->C1 &= (~0x30);
#define MMA8451Q_I2C_RepeatedStart() I2C0->C1 |= 0x04;
#define MMA8451Q_I2C_Disable_Ack() I2C0->C1 |= 0x08;
#define MMA8451Q_I2C_Enable_Ack() I2C0->C1 &= (~0x08);
#define MMA8451Q_I2C_Wait() \
while ((I2C0->S & 0x02) == 0) \
; \
I2C0->S |= 0x02;
#define MMA8451Q_I2C_EnterRxMode() I2C0->C1 &= (~0x10);
////////////////////////////////////////////////////
void MMA8451Q_I2C_Init(void);
void MMA8451Q_Init();
void MMA8451Q_WriteRegister(unsigned char u8RegisterAddress, unsigned char u8Data);
unsigned char MMA8451Q_ReadRegister(unsigned char u8RegisterAddress);

View File

@ -1,11 +1,7 @@
#pragma once
#include <inttypes.h>
#define ADC_M 1024
extern int16_t adc_buf[ADC_M];
extern int16_t pADC;
extern uint8_t fADC;
#include "derivative.h"
void adc0_Init();
int16_t adc0_TR_DATA();
void adc0_read_buf(int16_t *data, uint16_t len);

View File

@ -1,6 +1,12 @@
#pragma once
#include "CMSIS/MKL25Z4.h"
#include <inttypes.h>
#define q15_t int16_t
#define q31_t int32_t
#define float32_t float
typedef unsigned char uchar;
// Define Clock Settings
#define CORCLK_DEFAULT 20970000u // Default Core clock, 20.97 Mhz
@ -27,10 +33,10 @@
PORT##port->PCR[pin] |= PORT_PCR_PE(0x1); \
}
#define ticks_ms (uint32_t)(ticks_50us / 20)
#define ticks_ms (uint32_t)(ticks_100us / 10)
extern uint32_t CORCLK;
extern uint32_t BUSCLK;
extern volatile uint32_t ticks_50us;
extern volatile uint32_t ticks_100us;
extern void SysTick_Handler(void);
extern void UART1_IRQHandler(void);

View File

@ -1,11 +1,10 @@
#pragma once
#include <inttypes.h>
#include "derivative.h"
#define q15_t int16_t
#define q31_t int32_t
#define FFT_N 256
#define FFT_BIN(num, re) (uint16_t)((float)(num + 0.5) * re)
#define FFT_INDEX(freq, re) (uint16_t)((float)freq / re)
void FFT(q15_t *data);
void FFT(q15_t *data, uint16_t len);

View File

@ -2,8 +2,7 @@
#include "fft.h"
extern const q15_t hanning_17[];
extern const q15_t hanning_160[];
extern const q15_t hanning[];
extern const uint16_t bitrevTable[];
extern const q15_t rotCoef[];

View File

@ -1,21 +0,0 @@
#pragma once
#include <inttypes.h>
#define float32_t float
#define N 1024
#define FS 16000
#define RE FS / N
#define MN 256
#define FREQ_BIT1 1100
#define FREQ_SYNC 1200
#define FREQ_BIT0 1300
#define FREQ_START 1900
#define FREQ_BLACK 1500
#define FREQ_WHITE 4000
#define FREQ_RANGE FREQ_WHITE - FREQ_BLACK
#define COLOR_SCALE 64
uint8_t decode_sstv();

View File

@ -16,12 +16,12 @@ static inline bool timer_expired_ms(uint32_t *t, uint32_t prd) {
return true; // Expired, return true
}
static inline bool timer_expired_50us(uint32_t *t, uint32_t prd) {
if (ticks_50us + prd < *t) *t = 0; // Time wrapped? Reset timer
if (*t == 0) *t = ticks_50us + prd; // First poll? Set expiration
if (*t > ticks_50us) return false; // Not expired yet, return
*t = (ticks_50us - *t) > prd ? ticks_50us + prd : *t + prd; // Next expiration time
return true; // Expired, return true
static inline bool timer_expired_100us(uint32_t *t, uint32_t prd) {
if (ticks_100us + prd < *t) *t = 0; // Time wrapped? Reset timer
if (*t == 0) *t = ticks_100us + prd; // First poll? Set expiration
if (*t > ticks_100us) return false; // Not expired yet, return
*t = (ticks_100us - *t) > prd ? ticks_100us + prd : *t + prd; // Next expiration time
return true; // Expired, return true
}
static inline void delay_ms(uint32_t ms) {
@ -29,7 +29,7 @@ static inline void delay_ms(uint32_t ms) {
while (ticks_ms - start < ms) asm("nop");
}
static inline void delay_50us(uint32_t us) {
uint32_t start = ticks_50us;
while (ticks_50us - start < us) asm("nop");
static inline void delay_100us(uint32_t us) {
uint32_t start = ticks_100us;
while (ticks_100us - start < us) asm("nop");
}

View File

@ -29,8 +29,6 @@
#include "derivative.h"
typedef unsigned char uchar;
// LCD function 1 enable
#define USE_HORIZONTAL 1 // 横屏
#define LCD_FAST_IO 1 // 快速IO

49
include/tpm.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include "derivative.h"
#define PWMCLK 163828 // 20.97 MHz / 128
/*
@brief Timer / PWM Initialization
@param TPM (TPM0, TPM1, TPM2)
@param cha channel
*/
static inline void tpm_init(TPM_Type* TPM, uint8_t cha) {
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // MCGFLLCLK clock or MCGPLLCLK/2
SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK; // MCGFLLCLK clock
/*
CNT: Current Counter Value, 16 bits
MOD: Modulo Value, 16 bits -> Frequency
SC: Status and Control
CnSC: Channel (n) Status and Control
CnV: Channel (n) Value, 16 bits -> duty cycle
*/
if (TPM == TPM0) {
SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK;
} else if (TPM == TPM1) {
SIM->SCGC6 |= SIM_SCGC6_TPM1_MASK;
} else if (TPM == TPM2) {
SIM->SCGC6 |= SIM_SCGC6_TPM2_MASK;
}
TPM->CNT = 0x0;
TPM->MOD = 0x0;
TPM->SC |= TPM_SC_CMOD(1) // LPTPM counter increments on every LPTPM counter clock
| TPM_SC_PS(7); // Prescaler Factor, Divide by 128
TPM->CONTROLS[cha].CnSC |= TPM_CnSC_ELSB(1) | TPM_CnSC_ELSA(0) // High-true pulses
| TPM_CnSC_MSB(1) | TPM_CnSC_MSA(0); // Edge-aligned PWM
TPM->CONTROLS[cha].CnV = 0x0;
}
/*
@brief Set the frequency and duty cycle of the PWM
@param TPM (TPM0, TPM1, TPM2)
@param mod modulo value -> frequency
@param val threshold value, when the count exceeds the threshold output toggles -> duty cycle
@param cha channel
*/
static inline void tpm_set(TPM_Type* TPM, uint16_t mod, uint16_t val, uint8_t cha) {
TPM->MOD = mod;
TPM->CONTROLS[cha].CnV = val;
}

View File

@ -84,3 +84,9 @@ static inline size_t uart_getline(UART_Type *UART, char *buf) {
}
return cnt;
}
static inline void string_format(char *buf, const char *format, ...) {
va_list args;
va_start(args, format);
vsprintf(buf, format, args);
}

141
main.c
View File

@ -1,51 +1,118 @@
#include "adc.h"
#include "MMA8451Q.h"
#include "derivative.h"
#include "systick.h"
#include "tftlcd.h"
#include "tpm.h"
#include "uart.h"
#include <stdio.h>
#include <string.h>
#define L1 M1 * 2 // 低八度
#define L2 M2 * 2
#define L3 M3 * 2
#define L4 M4 * 2
#define L5 M5 * 2
#define L6 M6 * 2
#define L7 M7 * 2
#define M1 (unsigned short)(PWMCLK / 523)
#define M2 (unsigned short)(PWMCLK / 587)
#define M3 (unsigned short)(PWMCLK / 659)
#define M4 (unsigned short)(PWMCLK / 698)
#define M5 (unsigned short)(PWMCLK / 784)
#define M6 (unsigned short)(PWMCLK / 880)
#define M7 (unsigned short)(PWMCLK / 988)
#define H1 M1 / 2 // 高八度
#define H2 M2 / 2
#define H3 M3 / 2
#define H4 M4 / 2
#define H5 M5 / 2
#define H6 M6 / 2
#define H7 M7 / 2
#define NN 0 // 休止符
// 晴天 4/4拍 (以1/4音符为1拍每小节4拍)
#define N 204
#define BPM 67 // Beats Per Minute
const unsigned short note[] = {
NN, M5, M5, M1, M1, M2, M3, // 故事的小黄花
NN, M5, M5, M1, M1, M2, M3, M2, M1, L5, // 从出生那年就飘着
NN, M5, M5, M1, M1, M2, M3, // 童年的荡秋千
NN, M3, M2, M3, M4, M3, M2, M4, M3, M2, M1, // 随记忆一直晃到现在
L5, M1, M1, M3, M4, M3, M2, M1, M2, // rui sou sou xi dou xi la sou la
M3, M3, M3, M3, M2, M3, M2, M1, // xi xi xi xi la xi la sou
L5, M1, M2, M3, M4, M3, M2, M1, M2, // 吹着前奏望着天空 我
M3, M3, M3, M3, M2, M3, M2, M1, L7, // 想起花瓣试着掉落 为
M1, M1, M1, M1, L7, M1, M1, M1, M1, M1, M1, L7, M1, M1, // 你翘课的那一天 花落的那一天
M1, M1, M1, M1, L7, M1, M1, M1, M1, M1, M1, M5, M5, M5, // 教室的那一间 我怎么看不见
NN, M5, M5, M5, M5, M5, M5, M5, M5, M5, M5, M5, M4, M3, M3, // 消失的下雨天 我好想再淋一遍
M3, M3, NN, M1, M1, M1, M1, // 没想到失
L6, L7, M1, M5, M4, M3, M1, M1, // 去的勇气我还留着
M1, NN, M1, M1, M1, M1, M3, M1, // 好想再问一遍
L6, L7, M1, M5, M4, M3, M1, M2, // 你会等待还是离开
M2, M2, NN, NN, // Null
M3, M2, M4, M3, M1, M5, M7, // 刮风这天 我试过
H1, M7, M1, M1, M1, M6, M6, // 握着你手 但偏偏
NN, M6, M5, M5, M5, M4, M3, // 雨渐渐 大到我
M2, M3, M4, M3, M3, M3, // 看你不见
M3, M4, M5, M3, M4, M5, M7, // 还有多久 我才能
H2, M7, H1, H1, NN, H1, // 在你身边 等
H1, M5, M5, M6, M5, M4, M4, M2, M3, // 到放晴的那天 也许
M4, M5, M6, M1, M6, M7, M7, // 我会比较好一点
};
const unsigned short duration[] = {
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, // 故事的小黄花
0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, // 从出生那年就飘着
0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, // 童年的荡秋千
0x02, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, // 随记忆一直晃到现在
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, // rui sou sou xi dou xi la sou la
0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x04, // xi xi xi xi la xi la sou
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, // 吹着前奏望着天空 我
0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x03, 0x01, // 想起花瓣试着掉落 为
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, // 你翘课的那一天 花落的那一天
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, // 教室的那一间 我怎么看不见
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, // 消失的下雨天 我好想再淋一遍
0x04, 0x04, 0x04, 0x01, 0x01, 0x01, 0x01, // 没想到失
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 去的勇气我还留着
0x04, 0x04, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, // 好想再问一遍
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 你会等待还是离开
0x04, 0x04, 0x00, 0x00, // Null
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, // 刮风这天 我试过
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, // 握着你手 但偏偏
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, // 雨渐渐 大到我
0x02, 0x02, 0x02, 0x02, 0x04, 0x04, // 看你不见
0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, // 还有多久 我才能
0x02, 0x02, 0x02, 0x06, 0x02, 0x02, // 在你身边 等
0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, // 到放晴的那天 也许
0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x04, // 我会比较好一点
}; // 1/4音符为0x04, 最短为1/16音符
int main(void) {
// Initialize
uart_init(UART_MSG, 9600); // Initialize UART1 with PC
uart_rie_enable(UART_MSG); // Enable UART1 receive interrupt
LCD_Init(); // Initialize LCD
adc0_Init(); // Initialize ADC0
SysTick_Config(CORCLK / 1000); // Period of systick timer : 1 ms
tpm_init(TPM0, 4); // Initialize TPM0_CH4
LCD_Init(); // Initialize LCD
uart_printf(UART_MSG, "System Clock: %lu\r\n", CORCLK);
uart_printf(UART_MSG, "Bus Clock: %lu\r\n", BUSCLK);
// TMP0_CH4 -> PTC8
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
PORTC->PCR[8] = PORT_PCR_MUX(3); // Select TPM0_CH4
LCD_ShowString(LCD_W / 3, 0, "Audio Sample", 16, 0, 1);
LCD_DrawLine(0, 16, LCD_W - 1, 16);
LCD_ShowChar(30, 30, 65, 12, 0);
uint16_t x0 = 16, y0 = 32;
uint16_t x1 = LCD_W - 8, y1 = LCD_H - 16;
uint16_t ym = (y0 + y1) / 2;
LCD_DrawLine(x0, y0, x0, y1);
LCD_DrawLine(x0, ym, x1, ym);
LCD_ShowChar(0, y0, 'A', 16, 0);
LCD_ShowChar(x1, ym, 'T', 16, 0);
// uint16_t beat_time = (uint16_t)(60 * 1000.0 / BPM);
// uint32_t timer, period;
LCD_SetColor(BACK_COLOR);
// for (uint8_t i = 0;;) {
// period = (uint32_t)(duration[i] * beat_time / 0x04);
// timer = tick_cnt + period;
// while (tick_cnt < timer) {
// uint16_t delta = (uint16_t)(timer - tick_cnt);
// uint16_t val = (uint16_t)(note[i] / 2 * (period - delta) / period);
// tpm_set(TPM0, note[i], val, 4);
// }
// i = (uint8_t)((i + 1) % N);
int16_t res;
uint16_t pos[x1 - x0 - 1];
uint16_t x = x0 + 1, y;
uint32_t timer = 0;
fADC = 1;
for (;;) {
if (timer_expired_50us(&timer, 1)) {
LCD_DrawPoint(x, pos[x - x0 - 1], BACK_COLOR);
res = adc_buf[pADC];
y = ym + res * (y1 - ym) / 2048;
LCD_DrawPoint(x, y, RED);
LCD_DrawPoint(x, ym, BLACK);
pos[x - x0 - 1] = y;
x = x + 1 < x1 ? x + 1 : x0 + 1;
}
}
// if (timer_expired(&timer, period)) {
// tpm_set(TPM0, note[i], note[i] / 2, 4);
// i = (uint8_t)((i + 1) % N);
// }
}

110
src/MMA8451Q.c Normal file
View File

@ -0,0 +1,110 @@
#include "MMA8451Q.h"
#include "derivative.h"
#include "systick.h"
/*******************************************************************/
/*!
* I2C Initialization
* Set Baud Rate and turn on I2C0
*/
/*******************************************************************/
void MMA8451Q_I2C_Init(void) {
SIM->SCGC4 |= SIM_SCGC4_I2C0_MASK; // Turn on clock to I2C0 module
SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; // Turn on clock to PORTB module
/* configure GPIO for I2C0 function */
PORTE->PCR[24] = PORT_PCR_MUX(5);
PORTE->PCR[25] = PORT_PCR_MUX(5);
I2C0->F = 0x14; /* set MULT and ICR */
I2C0->C1 = 0x80; /* enable IIC */
}
/*******************************************************************/
/*!
* MMA8451Q Initialization
* Set MMA8451Q Control Register
*/
/*******************************************************************/
void MMA8451Q_Init() {
MMA8451Q_I2C_Init();
// MMA8451Q_ID=MMA8451Q_ReadRegister(0x0D); //read device ID
MMA8451Q_WriteRegister(0x2A, 0x01); // set MMA8451Q in ACTIVE mode
}
/*******************************************************************/
/*!
* Write a byte of Data to specified register on MMA8451Q
* @param u8RegisterAddress is Register Address
* @param u8Data is Data to write
*/
void MMA8451Q_WriteRegister(unsigned char u8RegisterAddress, unsigned char u8Data) {
/* send start signal */
MMA8451Q_I2C_Start();
/* send ID with W bit */
I2C0->D = ((MMA8451Q_I2C_ADDRESS << 1) | I2C_MWSR);
MMA8451Q_I2C_Wait();
/* Write Register Address */
I2C0->D = (u8RegisterAddress);
MMA8451Q_I2C_Wait();
/* Write Register Data */
I2C0->D = (u8Data);
MMA8451Q_I2C_Wait();
MMA8451Q_I2C_Stop();
spin(50);
}
/*******************************************************************/
/*!
* Read a register from the MMA8451Q
* @param u8RegisterAddress is Register Address
* @return Data stored in Register
*/
unsigned char MMA8451Q_ReadRegister(unsigned char u8RegisterAddress) {
unsigned char result;
/* send start signal */
MMA8451Q_I2C_Start();
/* send ID with W bit */
I2C0->D = ((MMA8451Q_I2C_ADDRESS << 1) | I2C_MWSR);
MMA8451Q_I2C_Wait();
/* Write Register Address */
I2C0->D = (u8RegisterAddress);
MMA8451Q_I2C_Wait();
/* Do a repeated start */
MMA8451Q_I2C_RepeatedStart();
/* send ID with R bit */
I2C0->D = ((MMA8451Q_I2C_ADDRESS << 1) | I2C_MRSW);
MMA8451Q_I2C_Wait();
/* Put in Rx Mode */
MMA8451Q_I2C_EnterRxMode();
/* Turn off ACK */
MMA8451Q_I2C_Disable_Ack();
/* Dummy read */
result = I2C0->D;
MMA8451Q_I2C_Wait();
/* Send stop */
MMA8451Q_I2C_Stop();
result = I2C0->D;
/* Turn on ACK */
MMA8451Q_I2C_Enable_Ack();
spin(50);
return result;
}

View File

@ -1,10 +1,6 @@
#include "adc.h"
#include "derivative.h"
int16_t adc_buf[ADC_M];
int16_t pADC = 0;
uint8_t fADC = 0;
void adc0_Init() {
// Enable ADC0 and PORTE clock
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;

View File

@ -5,13 +5,14 @@
uint32_t CORCLK = CORCLK_DEFAULT;
uint32_t BUSCLK = BUSCLK_DEFAULT;
volatile uint32_t ticks_50us;
volatile uint32_t ticks_100us;
void SysTick_Handler(void) {
ticks_50us++;
ticks_100us++;
if (fADC) {
adc_buf[pADC] = adc0_TR_DATA() - 1550;
pADC = (pADC + 1) % ADC_M;
cADC++;
}
}

View File

@ -1,18 +1,21 @@
#include "fft/fft.h"
#include "fft/table.h"
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#define N 1024
#define Re(x) 2 * x
#define Im(x) 2 * x + 1
static q15_t res[N * 2];
static q15_t res[FFT_N * 2];
static void applyWindow(q15_t *data, uint16_t len) {
for (uint16_t i = len; i < FFT_N; i++) data[i] = 0;
for (uint16_t i = 0; i < len; i++) data[i] = (q15_t)(((q31_t)data[i] * hanning[i]) >> 15);
}
static inline void bitreversal(q31_t *data) {
q31_t tmp;
uint16_t n1 = N >> 1;
uint16_t n1 = FFT_N >> 1;
uint16_t n2 = n1 + 1;
uint16_t *bitrev = (uint16_t *)&bitrevTable[0];
@ -39,7 +42,7 @@ static inline void butterfly(q15_t *data) {
uint16_t step = 1;
q15_t xt, yt, cosv, sinv;
for (uint16_t m = N; m > 1; m = m >> 1) {
for (uint16_t m = FFT_N; m > 1; m = m >> 1) {
uint16_t n1 = m;
uint16_t n2 = m >> 1;
@ -48,9 +51,9 @@ static inline void butterfly(q15_t *data) {
sinv = rotCoef[ia * 2 + 1];
ia = ia + step;
for (uint16_t j = i, k; j < N; j += n1) {
for (uint16_t j = i, k; j < FFT_N; j += n1) {
k = j + n2;
if (m == N) {
if (m == FFT_N) {
xt = (data[Re(j)] >> 2u) - (data[Re(k)] >> 2u);
yt = (data[Im(j)] >> 2u) - (data[Im(k)] >> 2u);
@ -84,13 +87,14 @@ static inline void butterfly(q15_t *data) {
}
}
void FFT(q15_t *data) {
for (uint16_t i = 0; i < N; i++) {
void FFT(q15_t *data, uint16_t len) {
applyWindow(data, len);
for (uint16_t i = 0; i < FFT_N; i++) {
res[Re(i)] = data[i]; // real
res[Im(i)] = 0; // imaginary
}
butterfly(res);
bitreversal((q31_t *)res);
for (uint16_t i = 0; i < N; i++) data[i] = (q15_t)abs(res[Re(i)]);
for (uint16_t i = 0; i < FFT_N; i++) data[i] = (q15_t)abs(res[Re(i)]);
}

View File

@ -1,24 +1,21 @@
#include "fft/table.h"
const q15_t hanning_17[] = {
0, 1247, 4799, 10114, 16384, 22654, 27969, 31521, 32767, 31521, 27969, 22654, 16384, 10114, 4799, 1247, 0,
};
const q15_t hanning_160[] = {
0, 13, 51, 115, 204, 319, 458, 623, 812, 1025, 1263, 1524, 1808, 2115, 2444, 2795,
3167, 3560, 3973, 4405, 4856, 5325, 5811, 6314, 6832, 7366, 7913, 8474, 9047, 9631, 10226, 10831,
11444, 12065, 12693, 13327, 13965, 14607, 15252, 15898, 16546, 17193, 17839, 18482, 19123, 19759, 20390, 21014,
21631, 22240, 22840, 23430, 24009, 24576, 25130, 25671, 26197, 26707, 27202, 27680, 28140, 28581, 29004, 29407,
29789, 30151, 30491, 30809, 31105, 31378, 31627, 31852, 32054, 32230, 32383, 32510, 32612, 32688, 32739, 32765,
32765, 32739, 32688, 32612, 32510, 32383, 32230, 32054, 31852, 31627, 31378, 31105, 30809, 30491, 30151, 29789,
29407, 29004, 28581, 28140, 27680, 27202, 26707, 26197, 25671, 25130, 24576, 24009, 23430, 22840, 22240, 21631,
21014, 20390, 19759, 19123, 18482, 17839, 17193, 16546, 15898, 15252, 14607, 13965, 13327, 12693, 12065, 11444,
10831, 10226, 9631, 9047, 8474, 7913, 7366, 6832, 6314, 5811, 5325, 4856, 4405, 3973, 3560, 3167,
2795, 2444, 2115, 1808, 1524, 1263, 1025, 812, 623, 458, 319, 204, 115, 51, 13, 0,
const q15_t hanning[] = {
0, 11, 43, 96, 171, 266, 383, 521, 679, 858, 1057, 1276, 1514, 1772, 2049, 2345,
2659, 2991, 3341, 3707, 4090, 4489, 4904, 5333, 5777, 6235, 6706, 7190, 7685, 8192, 8710, 9237,
9774, 10320, 10873, 11434, 12001, 12574, 13151, 13733, 14319, 14907, 15497, 16088, 16680, 17271, 17861, 18449,
19035, 19617, 20194, 20767, 21334, 21895, 22448, 22994, 23531, 24058, 24576, 25083, 25578, 26062, 26533, 26991,
27435, 27864, 28279, 28678, 29061, 29427, 29777, 30109, 30423, 30719, 30996, 31254, 31492, 31711, 31910, 32089,
32247, 32385, 32502, 32597, 32672, 32725, 32757, 32767, 32757, 32725, 32672, 32597, 32502, 32385, 32247, 32089,
31910, 31711, 31492, 31254, 30996, 30719, 30423, 30109, 29777, 29427, 29061, 28678, 28279, 27864, 27435, 26991,
26533, 26062, 25578, 25083, 24576, 24058, 23531, 22994, 22448, 21895, 21334, 20767, 20194, 19617, 19035, 18449,
17861, 17271, 16680, 16088, 15497, 14907, 14319, 13733, 13151, 12574, 12001, 11434, 10873, 10320, 9774, 9237,
8710, 8192, 7685, 7190, 6706, 6235, 5777, 5333, 4904, 4489, 4090, 3707, 3341, 2991, 2659, 2345,
2049, 1772, 1514, 1276, 1057, 858, 679, 521, 383, 266, 171, 96, 43, 11, 0,
};
/*
Table for bit reversal process, where N = 4096 logN2 = 12, N is the maximum FFT Size supported
Table for bit reversal process, where N = 256 logN2 = 8, N is the maximum FFT Size supported
for (l = 1; l <= N / 4; l++) {
for (i = 0; i < logN2; i++) {
a[i] = l & (1 << i);
@ -29,22 +26,11 @@ const q15_t hanning_160[] = {
y[l] = y[l] >> 1;
}
*/
const uint16_t bitrevTable[256] = {
0x100, 0x80, 0x180, 0x40, 0x140, 0xc0, 0x1c0, 0x20, 0x120, 0xa0, 0x1a0, 0x60, 0x160, 0xe0, 0x1e0, 0x10, 0x110, 0x90,
0x190, 0x50, 0x150, 0xd0, 0x1d0, 0x30, 0x130, 0xb0, 0x1b0, 0x70, 0x170, 0xf0, 0x1f0, 0x8, 0x108, 0x88, 0x188, 0x48,
0x148, 0xc8, 0x1c8, 0x28, 0x128, 0xa8, 0x1a8, 0x68, 0x168, 0xe8, 0x1e8, 0x18, 0x118, 0x98, 0x198, 0x58, 0x158, 0xd8,
0x1d8, 0x38, 0x138, 0xb8, 0x1b8, 0x78, 0x178, 0xf8, 0x1f8, 0x4, 0x104, 0x84, 0x184, 0x44, 0x144, 0xc4, 0x1c4, 0x24,
0x124, 0xa4, 0x1a4, 0x64, 0x164, 0xe4, 0x1e4, 0x14, 0x114, 0x94, 0x194, 0x54, 0x154, 0xd4, 0x1d4, 0x34, 0x134, 0xb4,
0x1b4, 0x74, 0x174, 0xf4, 0x1f4, 0xc, 0x10c, 0x8c, 0x18c, 0x4c, 0x14c, 0xcc, 0x1cc, 0x2c, 0x12c, 0xac, 0x1ac, 0x6c,
0x16c, 0xec, 0x1ec, 0x1c, 0x11c, 0x9c, 0x19c, 0x5c, 0x15c, 0xdc, 0x1dc, 0x3c, 0x13c, 0xbc, 0x1bc, 0x7c, 0x17c, 0xfc,
0x1fc, 0x2, 0x102, 0x82, 0x182, 0x42, 0x142, 0xc2, 0x1c2, 0x22, 0x122, 0xa2, 0x1a2, 0x62, 0x162, 0xe2, 0x1e2, 0x12,
0x112, 0x92, 0x192, 0x52, 0x152, 0xd2, 0x1d2, 0x32, 0x132, 0xb2, 0x1b2, 0x72, 0x172, 0xf2, 0x1f2, 0xa, 0x10a, 0x8a,
0x18a, 0x4a, 0x14a, 0xca, 0x1ca, 0x2a, 0x12a, 0xaa, 0x1aa, 0x6a, 0x16a, 0xea, 0x1ea, 0x1a, 0x11a, 0x9a, 0x19a, 0x5a,
0x15a, 0xda, 0x1da, 0x3a, 0x13a, 0xba, 0x1ba, 0x7a, 0x17a, 0xfa, 0x1fa, 0x6, 0x106, 0x86, 0x186, 0x46, 0x146, 0xc6,
0x1c6, 0x26, 0x126, 0xa6, 0x1a6, 0x66, 0x166, 0xe6, 0x1e6, 0x16, 0x116, 0x96, 0x196, 0x56, 0x156, 0xd6, 0x1d6, 0x36,
0x136, 0xb6, 0x1b6, 0x76, 0x176, 0xf6, 0x1f6, 0xe, 0x10e, 0x8e, 0x18e, 0x4e, 0x14e, 0xce, 0x1ce, 0x2e, 0x12e, 0xae,
0x1ae, 0x6e, 0x16e, 0xee, 0x1ee, 0x1e, 0x11e, 0x9e, 0x19e, 0x5e, 0x15e, 0xde, 0x1de, 0x3e, 0x13e, 0xbe, 0x1be, 0x7e,
0x17e, 0xfe, 0x1fe, 0x1,
const uint16_t bitrevTable[64] = {
0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, 0x8, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78, 0x4,
0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74, 0xc, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c, 0x2,
0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72, 0xa, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a, 0x6,
0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76, 0xe, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e, 0x1,
};
/*
@ -53,117 +39,36 @@ const uint16_t bitrevTable[256] = {
rotCoef[2 * i] = cos(i * 2 * PI / (float)N);
rotCoef[2 * i + 1] = sin(i * 2 * PI / (float)N);
}
where N = 1024 and PI = 3.14159265358979, Cos and Sin values are interleaved fashion
where N = 256 and PI = 3.14159265358979, Cos and Sin values are interleaved fashion
Convert Floating point to int16 round(rotCoef(i) * pow(2, 15))
*/
const q15_t rotCoef[1536] = {
32767, 0, 32766, 201, 32765, 402, 32761, 603, 32757, 804, 32752, 1005, 32745, 1206,
32737, 1407, 32728, 1608, 32717, 1809, 32705, 2009, 32692, 2210, 32678, 2410, 32663, 2611,
32646, 2811, 32628, 3012, 32609, 3212, 32589, 3412, 32567, 3612, 32545, 3811, 32521, 4011,
32495, 4210, 32469, 4410, 32441, 4609, 32412, 4808, 32382, 5007, 32351, 5205, 32318, 5404,
32285, 5602, 32250, 5800, 32213, 5998, 32176, 6195, 32137, 6393, 32098, 6590, 32057, 6786,
32014, 6983, 31971, 7179, 31926, 7375, 31880, 7571, 31833, 7767, 31785, 7962, 31736, 8157,
31685, 8351, 31633, 8545, 31580, 8739, 31526, 8933, 31470, 9126, 31414, 9319, 31356, 9512,
31297, 9704, 31237, 9896, 31176, 10087, 31113, 10278, 31050, 10469, 30985, 10659, 30919, 10849,
30852, 11039, 30783, 11228, 30714, 11417, 30643, 11605, 30571, 11793, 30498, 11980, 30424, 12167,
30349, 12353, 30273, 12539, 30195, 12725, 30117, 12910, 30037, 13094, 29956, 13279, 29874, 13462,
29791, 13645, 29706, 13828, 29621, 14010, 29534, 14191, 29447, 14372, 29358, 14553, 29268, 14732,
29177, 14912, 29085, 15090, 28992, 15269, 28898, 15446, 28803, 15623, 28706, 15800, 28609, 15976,
28510, 16151, 28411, 16325, 28310, 16499, 28208, 16673, 28105, 16846, 28001, 17018, 27896, 17189,
27790, 17360, 27683, 17530, 27575, 17700, 27466, 17869, 27356, 18037, 27245, 18204, 27133, 18371,
27019, 18537, 26905, 18703, 26790, 18868, 26674, 19032, 26556, 19195, 26438, 19357, 26319, 19519,
26198, 19680, 26077, 19841, 25955, 20000, 25832, 20159, 25708, 20317, 25582, 20475, 25456, 20631,
25329, 20787, 25201, 20942, 25072, 21096, 24942, 21250, 24811, 21403, 24680, 21554, 24547, 21705,
24413, 21856, 24279, 22005, 24143, 22154, 24007, 22301, 23870, 22448, 23731, 22594, 23592, 22739,
23452, 22884, 23311, 23027, 23170, 23170, 23027, 23311, 22884, 23452, 22739, 23592, 22594, 23731,
22448, 23870, 22301, 24007, 22154, 24143, 22005, 24279, 21856, 24413, 21705, 24547, 21554, 24680,
21403, 24811, 21250, 24942, 21096, 25072, 20942, 25201, 20787, 25329, 20631, 25456, 20475, 25582,
20317, 25708, 20159, 25832, 20000, 25955, 19841, 26077, 19680, 26198, 19519, 26319, 19357, 26438,
19195, 26556, 19032, 26674, 18868, 26790, 18703, 26905, 18537, 27019, 18371, 27133, 18204, 27245,
18037, 27356, 17869, 27466, 17700, 27575, 17530, 27683, 17360, 27790, 17189, 27896, 17018, 28001,
16846, 28105, 16673, 28208, 16499, 28310, 16325, 28411, 16151, 28510, 15976, 28609, 15800, 28706,
15623, 28803, 15446, 28898, 15269, 28992, 15090, 29085, 14912, 29177, 14732, 29268, 14553, 29358,
14372, 29447, 14191, 29534, 14010, 29621, 13828, 29706, 13645, 29791, 13462, 29874, 13279, 29956,
13094, 30037, 12910, 30117, 12725, 30195, 12539, 30273, 12353, 30349, 12167, 30424, 11980, 30498,
11793, 30571, 11605, 30643, 11417, 30714, 11228, 30783, 11039, 30852, 10849, 30919, 10659, 30985,
10469, 31050, 10278, 31113, 10087, 31176, 9896, 31237, 9704, 31297, 9512, 31356, 9319, 31414,
9126, 31470, 8933, 31526, 8739, 31580, 8545, 31633, 8351, 31685, 8157, 31736, 7962, 31785,
7767, 31833, 7571, 31880, 7375, 31926, 7179, 31971, 6983, 32014, 6786, 32057, 6590, 32098,
6393, 32137, 6195, 32176, 5998, 32213, 5800, 32250, 5602, 32285, 5404, 32318, 5205, 32351,
5007, 32382, 4808, 32412, 4609, 32441, 4410, 32469, 4210, 32495, 4011, 32521, 3811, 32545,
3612, 32567, 3412, 32589, 3212, 32609, 3012, 32628, 2811, 32646, 2611, 32663, 2410, 32678,
2210, 32692, 2009, 32705, 1809, 32717, 1608, 32728, 1407, 32737, 1206, 32745, 1005, 32752,
804, 32757, 603, 32761, 402, 32765, 201, 32766, 0, 32767, -201, 32766, -402, 32765,
-603, 32761, -804, 32757, -1005, 32752, -1206, 32745, -1407, 32737, -1608, 32728, -1809, 32717,
-2009, 32705, -2210, 32692, -2410, 32678, -2611, 32663, -2811, 32646, -3012, 32628, -3212, 32609,
-3412, 32589, -3612, 32567, -3811, 32545, -4011, 32521, -4210, 32495, -4410, 32469, -4609, 32441,
-4808, 32412, -5007, 32382, -5205, 32351, -5404, 32318, -5602, 32285, -5800, 32250, -5998, 32213,
-6195, 32176, -6393, 32137, -6590, 32098, -6786, 32057, -6983, 32014, -7179, 31971, -7375, 31926,
-7571, 31880, -7767, 31833, -7962, 31785, -8157, 31736, -8351, 31685, -8545, 31633, -8739, 31580,
-8933, 31526, -9126, 31470, -9319, 31414, -9512, 31356, -9704, 31297, -9896, 31237, -10087, 31176,
-10278, 31113, -10469, 31050, -10659, 30985, -10849, 30919, -11039, 30852, -11228, 30783, -11417, 30714,
-11605, 30643, -11793, 30571, -11980, 30498, -12167, 30424, -12353, 30349, -12539, 30273, -12725, 30195,
-12910, 30117, -13094, 30037, -13279, 29956, -13462, 29874, -13645, 29791, -13828, 29706, -14010, 29621,
-14191, 29534, -14372, 29447, -14553, 29358, -14732, 29268, -14912, 29177, -15090, 29085, -15269, 28992,
-15446, 28898, -15623, 28803, -15800, 28706, -15976, 28609, -16151, 28510, -16325, 28411, -16499, 28310,
-16673, 28208, -16846, 28105, -17018, 28001, -17189, 27896, -17360, 27790, -17530, 27683, -17700, 27575,
-17869, 27466, -18037, 27356, -18204, 27245, -18371, 27133, -18537, 27019, -18703, 26905, -18868, 26790,
-19032, 26674, -19195, 26556, -19357, 26438, -19519, 26319, -19680, 26198, -19841, 26077, -20000, 25955,
-20159, 25832, -20317, 25708, -20475, 25582, -20631, 25456, -20787, 25329, -20942, 25201, -21096, 25072,
-21250, 24942, -21403, 24811, -21554, 24680, -21705, 24547, -21856, 24413, -22005, 24279, -22154, 24143,
-22301, 24007, -22448, 23870, -22594, 23731, -22739, 23592, -22884, 23452, -23027, 23311, -23170, 23170,
-23311, 23027, -23452, 22884, -23592, 22739, -23731, 22594, -23870, 22448, -24007, 22301, -24143, 22154,
-24279, 22005, -24413, 21856, -24547, 21705, -24680, 21554, -24811, 21403, -24942, 21250, -25072, 21096,
-25201, 20942, -25329, 20787, -25456, 20631, -25582, 20475, -25708, 20317, -25832, 20159, -25955, 20000,
-26077, 19841, -26198, 19680, -26319, 19519, -26438, 19357, -26556, 19195, -26674, 19032, -26790, 18868,
-26905, 18703, -27019, 18537, -27133, 18371, -27245, 18204, -27356, 18037, -27466, 17869, -27575, 17700,
-27683, 17530, -27790, 17360, -27896, 17189, -28001, 17018, -28105, 16846, -28208, 16673, -28310, 16499,
-28411, 16325, -28510, 16151, -28609, 15976, -28706, 15800, -28803, 15623, -28898, 15446, -28992, 15269,
-29085, 15090, -29177, 14912, -29268, 14732, -29358, 14553, -29447, 14372, -29534, 14191, -29621, 14010,
-29706, 13828, -29791, 13645, -29874, 13462, -29956, 13279, -30037, 13094, -30117, 12910, -30195, 12725,
-30273, 12539, -30349, 12353, -30424, 12167, -30498, 11980, -30571, 11793, -30643, 11605, -30714, 11417,
-30783, 11228, -30852, 11039, -30919, 10849, -30985, 10659, -31050, 10469, -31113, 10278, -31176, 10087,
-31237, 9896, -31297, 9704, -31356, 9512, -31414, 9319, -31470, 9126, -31526, 8933, -31580, 8739,
-31633, 8545, -31685, 8351, -31736, 8157, -31785, 7962, -31833, 7767, -31880, 7571, -31926, 7375,
-31971, 7179, -32014, 6983, -32057, 6786, -32098, 6590, -32137, 6393, -32176, 6195, -32213, 5998,
-32250, 5800, -32285, 5602, -32318, 5404, -32351, 5205, -32382, 5007, -32412, 4808, -32441, 4609,
-32469, 4410, -32495, 4210, -32521, 4011, -32545, 3811, -32567, 3612, -32589, 3412, -32609, 3212,
-32628, 3012, -32646, 2811, -32663, 2611, -32678, 2410, -32692, 2210, -32705, 2009, -32717, 1809,
-32728, 1608, -32737, 1407, -32745, 1206, -32752, 1005, -32757, 804, -32761, 603, -32765, 402,
-32766, 201, -32767, 0, -32766, -201, -32765, -402, -32761, -603, -32757, -804, -32752, -1005,
-32745, -1206, -32737, -1407, -32728, -1608, -32717, -1809, -32705, -2009, -32692, -2210, -32678, -2410,
-32663, -2611, -32646, -2811, -32628, -3012, -32609, -3212, -32589, -3412, -32567, -3612, -32545, -3811,
-32521, -4011, -32495, -4210, -32469, -4410, -32441, -4609, -32412, -4808, -32382, -5007, -32351, -5205,
-32318, -5404, -32285, -5602, -32250, -5800, -32213, -5998, -32176, -6195, -32137, -6393, -32098, -6590,
-32057, -6786, -32014, -6983, -31971, -7179, -31926, -7375, -31880, -7571, -31833, -7767, -31785, -7962,
-31736, -8157, -31685, -8351, -31633, -8545, -31580, -8739, -31526, -8933, -31470, -9126, -31414, -9319,
-31356, -9512, -31297, -9704, -31237, -9896, -31176, -10087, -31113, -10278, -31050, -10469, -30985, -10659,
-30919, -10849, -30852, -11039, -30783, -11228, -30714, -11417, -30643, -11605, -30571, -11793, -30498, -11980,
-30424, -12167, -30349, -12353, -30273, -12539, -30195, -12725, -30117, -12910, -30037, -13094, -29956, -13279,
-29874, -13462, -29791, -13645, -29706, -13828, -29621, -14010, -29534, -14191, -29447, -14372, -29358, -14553,
-29268, -14732, -29177, -14912, -29085, -15090, -28992, -15269, -28898, -15446, -28803, -15623, -28706, -15800,
-28609, -15976, -28510, -16151, -28411, -16325, -28310, -16499, -28208, -16673, -28105, -16846, -28001, -17018,
-27896, -17189, -27790, -17360, -27683, -17530, -27575, -17700, -27466, -17869, -27356, -18037, -27245, -18204,
-27133, -18371, -27019, -18537, -26905, -18703, -26790, -18868, -26674, -19032, -26556, -19195, -26438, -19357,
-26319, -19519, -26198, -19680, -26077, -19841, -25955, -20000, -25832, -20159, -25708, -20317, -25582, -20475,
-25456, -20631, -25329, -20787, -25201, -20942, -25072, -21096, -24942, -21250, -24811, -21403, -24680, -21554,
-24547, -21705, -24413, -21856, -24279, -22005, -24143, -22154, -24007, -22301, -23870, -22448, -23731, -22594,
-23592, -22739, -23452, -22884, -23311, -23027, -23170, -23170, -23027, -23311, -22884, -23452, -22739, -23592,
-22594, -23731, -22448, -23870, -22301, -24007, -22154, -24143, -22005, -24279, -21856, -24413, -21705, -24547,
-21554, -24680, -21403, -24811, -21250, -24942, -21096, -25072, -20942, -25201, -20787, -25329, -20631, -25456,
-20475, -25582, -20317, -25708, -20159, -25832, -20000, -25955, -19841, -26077, -19680, -26198, -19519, -26319,
-19357, -26438, -19195, -26556, -19032, -26674, -18868, -26790, -18703, -26905, -18537, -27019, -18371, -27133,
-18204, -27245, -18037, -27356, -17869, -27466, -17700, -27575, -17530, -27683, -17360, -27790, -17189, -27896,
-17018, -28001, -16846, -28105, -16673, -28208, -16499, -28310, -16325, -28411, -16151, -28510, -15976, -28609,
-15800, -28706, -15623, -28803, -15446, -28898, -15269, -28992, -15090, -29085, -14912, -29177, -14732, -29268,
-14553, -29358, -14372, -29447, -14191, -29534, -14010, -29621, -13828, -29706, -13645, -29791, -13462, -29874,
-13279, -29956, -13094, -30037, -12910, -30117, -12725, -30195, -12539, -30273, -12353, -30349, -12167, -30424,
-11980, -30498, -11793, -30571, -11605, -30643, -11417, -30714, -11228, -30783, -11039, -30852, -10849, -30919,
-10659, -30985, -10469, -31050, -10278, -31113, -10087, -31176, -9896, -31237, -9704, -31297, -9512, -31356,
-9319, -31414, -9126, -31470, -8933, -31526, -8739, -31580, -8545, -31633, -8351, -31685, -8157, -31736,
-7962, -31785, -7767, -31833, -7571, -31880, -7375, -31926, -7179, -31971, -6983, -32014, -6786, -32057,
-6590, -32098, -6393, -32137, -6195, -32176, -5998, -32213, -5800, -32250, -5602, -32285, -5404, -32318,
-5205, -32351, -5007, -32382, -4808, -32412, -4609, -32441, -4410, -32469, -4210, -32495, -4011, -32521,
-3811, -32545, -3612, -32567, -3412, -32589, -3212, -32609, -3012, -32628, -2811, -32646, -2611, -32663,
-2410, -32678, -2210, -32692, -2009, -32705, -1809, -32717, -1608, -32728, -1407, -32737, -1206, -32745,
-1005, -32752, -804, -32757, -603, -32761, -402, -32765, -201, -32766};
const q15_t rotCoef[384] = {
32767, 0, 32757, 804, 32728, 1608, 32678, 2410, 32609, 3212, 32521, 4011, 32412, 4808,
32285, 5602, 32137, 6393, 31971, 7179, 31785, 7962, 31580, 8739, 31356, 9512, 31113, 10278,
30852, 11039, 30571, 11793, 30273, 12539, 29956, 13279, 29621, 14010, 29268, 14732, 28898, 15446,
28510, 16151, 28105, 16846, 27683, 17530, 27245, 18204, 26790, 18868, 26319, 19519, 25832, 20159,
25329, 20787, 24811, 21403, 24279, 22005, 23731, 22594, 23170, 23170, 22594, 23731, 22005, 24279,
21403, 24811, 20787, 25329, 20159, 25832, 19519, 26319, 18868, 26790, 18204, 27245, 17530, 27683,
16846, 28105, 16151, 28510, 15446, 28898, 14732, 29268, 14010, 29621, 13279, 29956, 12539, 30273,
11793, 30571, 11039, 30852, 10278, 31113, 9512, 31356, 8739, 31580, 7962, 31785, 7179, 31971,
6393, 32137, 5602, 32285, 4808, 32412, 4011, 32521, 3212, 32609, 2410, 32678, 1608, 32728,
804, 32757, 0, 32767, -804, 32757, -1608, 32728, -2410, 32678, -3212, 32609, -4011, 32521,
-4808, 32412, -5602, 32285, -6393, 32137, -7179, 31971, -7962, 31785, -8739, 31580, -9512, 31356,
-10278, 31113, -11039, 30852, -11793, 30571, -12539, 30273, -13279, 29956, -14010, 29621, -14732, 29268,
-15446, 28898, -16151, 28510, -16846, 28105, -17530, 27683, -18204, 27245, -18868, 26790, -19519, 26319,
-20159, 25832, -20787, 25329, -21403, 24811, -22005, 24279, -22594, 23731, -23170, 23170, -23731, 22594,
-24279, 22005, -24811, 21403, -25329, 20787, -25832, 20159, -26319, 19519, -26790, 18868, -27245, 18204,
-27683, 17530, -28105, 16846, -28510, 16151, -28898, 15446, -29268, 14732, -29621, 14010, -29956, 13279,
-30273, 12539, -30571, 11793, -30852, 11039, -31113, 10278, -31356, 9512, -31580, 8739, -31785, 7962,
-31971, 7179, -32137, 6393, -32285, 5602, -32412, 4808, -32521, 4011, -32609, 3212, -32678, 2410,
-32728, 1608, -32757, 804, -32767, 0, -32757, -804, -32728, -1608, -32678, -2410, -32609, -3212,
-32521, -4011, -32412, -4808, -32285, -5602, -32137, -6393, -31971, -7179, -31785, -7962, -31580, -8739,
-31356, -9512, -31113, -10278, -30852, -11039, -30571, -11793, -30273, -12539, -29956, -13279, -29621, -14010,
-29268, -14732, -28898, -15446, -28510, -16151, -28105, -16846, -27683, -17530, -27245, -18204, -26790, -18868,
-26319, -19519, -25832, -20159, -25329, -20787, -24811, -21403, -24279, -22005, -23731, -22594, -23170, -23170,
-22594, -23731, -22005, -24279, -21403, -24811, -20787, -25329, -20159, -25832, -19519, -26319, -18868, -26790,
-18204, -27245, -17530, -27683, -16846, -28105, -16151, -28510, -15446, -28898, -14732, -29268, -14010, -29621,
-13279, -29956, -12539, -30273, -11793, -30571, -11039, -30852, -10278, -31113, -9512, -31356, -8739, -31580,
-7962, -31785, -7179, -31971, -6393, -32137, -5602, -32285, -4808, -32412, -4011, -32521, -3212, -32609,
-2410, -32678, -1608, -32728, -804, -32757,
};

View File

@ -1,207 +0,0 @@
#include "derivative.h"
#include "fft/fft.h"
#include "fft/table.h"
#include "math.h"
#include "sstv.h"
#include <stdio.h>
#include <stdlib.h>
static q15_t data[N];
static q15_t buffer[MN];
static q15_t* pData = &data[0];
static uint8_t colorBuf[960];
static const float32_t color_re = (float32_t)(FREQ_RANGE) / (COLOR_SCALE - 1);
#define fre2lum(fre) (uint8_t)((fre - FREQ_BLACK) / color_re)
static q15_t img[1843202];
static q15_t* pImg = &img[0];
void init() {
FILE* fp;
fp = fopen("temp/data.txt", "r");
for (int i = 0; i < 1843202; i++) fscanf(fp, "%" SCNd16, &img[i]);
}
static void read_data(q15_t* pSrc, uint16_t len) {
for (int i = 0; i < len; i++) pSrc[i] = *pImg++;
}
static uint16_t find_peak(uint16_t L, uint16_t R) {
q15_t peak = 0;
uint16_t index = 0;
for (uint16_t i = L; i <= R; i++)
if (data[i] > peak) {
index = i;
peak = data[i];
}
return index;
}
static void hanning(uint16_t len) {
for (uint16_t i = len; i < N; i++) data[i] = 0;
if (len == 160)
for (uint16_t i = 0; i < len; i++) data[i] = (q15_t)(((q31_t)data[i] * hanning_160[i]) >> 15);
else
for (uint16_t i = 0; i < len; i++) data[i] = (q15_t)(((q31_t)data[i] * hanning_17[i]) >> 15);
}
static uint32_t cSample = 0;
static uint16_t preLen = 0;
static void read_samples(uint32_t start, uint16_t len) {
int16_t offset = start - cSample;
if (offset >= 0) {
read_data(pData, offset);
read_data(pData, len);
} else {
for (uint16_t i = 0; i < -offset; i++) data[i] = buffer[preLen + offset + i];
read_data(pData - offset, len + offset);
}
for (uint16_t i = 0; i < len; i++) buffer[i] = data[i];
cSample += offset + len;
preLen = len;
}
static void read_header() {
uint8_t cLeader1, cLeader2, cBreak, cVis;
uint16_t len = (uint16_t)(FS * 0.01);
uint16_t idx, fre;
cLeader1 = cLeader2 = cBreak = cVis = 0;
for (;;) {
read_data(pData, len);
hanning(len);
FFT(pData);
idx = find_peak(64, 128); // 1000 - 2000 Hz
fre = FFT_BIN(idx, RE);
if (abs(fre - FREQ_START) < 80) {
if (cBreak) cLeader2++;
else cLeader1++;
} else if (abs(fre - FREQ_SYNC) < 80) {
if (cLeader2) cVis++;
else cBreak++;
} else cLeader1 = cLeader2 = cBreak = cVis = 0;
if (cLeader1 > 5 // Leader tone
&& cBreak < 3 // Break
&& abs(cLeader2 - 30) < 5 // Leader tone
&& (cVis == 3 || cVis == 4) // VIS start bit
) {
printf("Header: %d %d %d %d\r\n", cLeader1, cBreak, cLeader2, cVis);
break;
}
}
}
static uint8_t read_mode() {
uint16_t len = (uint16_t)(FS * 0.01);
uint16_t idx, fre;
uint8_t cBit1 = 0, cParity = 0, mode = 0;
for (uint8_t i = 0; i < 24; i++) {
read_data(pData, len);
hanning(len);
FFT(pData);
idx = find_peak(64, 128); // 1000 - 2000 Hz
fre = FFT_BIN(idx, RE);
if (abs(fre - FREQ_BIT1) < 80) cBit1++;
else if (abs(fre - FREQ_BIT0) > 80) {
printf("Error VIS BIT: %d\r\n", fre);
return 0;
}
if (i % 3 == 2) {
mode = mode >> 1;
if (cBit1 > 1) {
mode |= BIT(7);
if (i != 23) cParity++;
}
cBit1 = 0;
}
}
cParity = (mode & BIT(7) ? 1 : 0) == (cParity % 2);
mode = mode & (~BIT(7));
if (!cParity) {
printf("Error Parity Check: %d\r\n", mode);
return 0;
}
read_data(pData, len * 3);
return mode;
}
static void decode_martin1() {
FILE* fp;
fp = fopen("temp/decode.txt", "w");
printf("Mode: 44 - Martin 1\r\n");
const uint16_t WIDTH = 320;
const uint16_t HEIGHT = 256;
const float32_t SCAN_TIME = 0.146432;
const float32_t SYNC_PULSE = 0.004862;
const float32_t SYNC_PORCH = 0.000572;
const float32_t CHAN_TIME = SYNC_PORCH + SCAN_TIME;
const float32_t LINE_TIME = SYNC_PULSE + SYNC_PORCH + CHAN_TIME * 3;
const float32_t PIXEL_TIME = SCAN_TIME / WIDTH;
const float32_t CHAN_OFFSETS[] = {
SYNC_PULSE + SYNC_PORCH,
SYNC_PULSE + SYNC_PORCH + CHAN_TIME,
SYNC_PULSE + SYNC_PORCH + CHAN_TIME * 2,
};
const float32_t FWHM = 2.34;
const float32_t HALF_SAMPLE_TIME = (PIXEL_TIME * FWHM) / 2;
const uint8_t len = (uint8_t)(HALF_SAMPLE_TIME * 2 * FS);
uint16_t idx, fre;
uint32_t start, cSampleI = 0;
float32_t cSampleF = 0;
printf("Start Decoding\r\n");
for (uint16_t h = 0; h < HEIGHT; h++) {
printf("Line: %d / 255\r\n", h);
if (h) {
cSampleF += LINE_TIME * FS;
cSampleI = (uint32_t)round(cSampleF);
}
for (uint8_t c = 0; c < 3; c++) {
for (uint16_t w = 0; w < WIDTH; w++) {
start = (uint32_t)round(cSampleI + (CHAN_OFFSETS[c] + w * PIXEL_TIME - HALF_SAMPLE_TIME) * FS);
read_samples(start, len);
hanning(len);
FFT(pData);
idx = find_peak(119, 457); // 1875 - 7125 Hz
fre = FFT_BIN(idx, RE);
colorBuf[w + WIDTH * c] = fre2lum(fre);
}
}
for (uint16_t w = 0; w < WIDTH; w++)
fprintf(fp, "%d %d %d \r\n", colorBuf[w + WIDTH * 2], colorBuf[w], colorBuf[w + WIDTH]);
}
}
uint8_t decode_sstv() {
uint8_t mode;
init();
read_header();
mode = read_mode();
if (mode == 44) decode_martin1();
else {
printf("Mode Error: %d\r\n", mode);
return 1;
}
return 0;
}

View File

@ -159,7 +159,7 @@ __attribute__((naked, noreturn)) void _reset(void) {
copy_data();
clock_init();
SysTick_Config(CORCLK / 100000 * 5); // Period of systick timer : 50 us
SysTick_Config(CORCLK / 100000 * 10); // Period of systick timer : 100 us
main();
for (;;) (void)0;