###################################################
-PROJ_NAME=stm32f4_codec2
FLOAT_TYPE=hard
###################################################
###################################################
-# Sources
-
-SRCS = main.c gdb_stdio.c stm32f4_timer.c system_stm32f4xx.c
-
# Codec 2
CODEC2_SRC=../src
-SRCS += \
+CODEC2_SRCS=\
$(CODEC2_SRC)/lpc.c \
$(CODEC2_SRC)/nlp.c \
$(CODEC2_SRC)/postfilter.c \
$(CODEC2_SRC)/codebookd.c \
$(CODEC2_SRC)/codebookjvm.c \
$(CODEC2_SRC)/codebookge.c \
-$(CODEC2_SRC)/dump.c
+$(CODEC2_SRC)/dump.c \
+$(CODEC2_SRC)/fdmdv.c
CFLAGS += -D__EMBEDDED__ -DTIMER
###################################################
-all: libstm32f4.a $(PROJ_NAME).elf fft_test.elf dac_ut.elf dac_play.elf adc_rec.elf pwm_ut.elf power_ut.elf
+all: libstm32f4.a codec2_profile.elf fft_test.elf dac_ut.elf dac_play.elf adc_rec.elf pwm_ut.elf power_ut.elf fdmdv_profile.elf
dl/$(PERIPHLIBZIP):
mkdir -p dl
for F in $(CMSIS)/DSP_Lib/Source/*/*.c ; do $(MAKE) $${F%.c}.o ; done
find $(PERIPHLIBDIR) -type f -name '*.o' -exec $(AR) crs libstm32f4.a {} ";"
-$(PROJ_NAME).elf: $(SRCS)
+####################################################
+
+CODEC2_PROFILE_SRCS=\
+src/codec2_profile.c \
+src/gdb_stdio.c \
+src/stm32f4_timer.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+src/system_stm32f4xx.c
+CODEC2_PROFILE_SRCS += $(CODEC2_SRCS)
+
+codec2_profile.elf: $(CODEC2_PROFILE_SRCS)
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
fft_test.elf: $(FFT_TEST_SRCS)
src/init.c \
src/stm32f4_timer.c \
-POWER_UT_SRCS += \
-$(CODEC2_SRC)/lpc.c \
-$(CODEC2_SRC)/nlp.c \
-$(CODEC2_SRC)/postfilter.c \
-$(CODEC2_SRC)/sine.c \
-$(CODEC2_SRC)/codec2.c \
-$(CODEC2_SRC)/kiss_fft.c \
-$(CODEC2_SRC)/interp.c \
-$(CODEC2_SRC)/lsp.c \
-$(CODEC2_SRC)/phase.c \
-$(CODEC2_SRC)/quantise.c \
-$(CODEC2_SRC)/pack.c \
-$(CODEC2_SRC)/codebook.c \
-$(CODEC2_SRC)/codebookd.c \
-$(CODEC2_SRC)/codebookjvm.c \
-$(CODEC2_SRC)/codebookge.c \
-$(CODEC2_SRC)/dump.c
+POWER_UT_SRCS += $(CODEC2_SRCS)
power_ut.elf: $(POWER_UT_SRCS)
$(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+FDMDV_PROFILE_SRCS=\
+src/fdmdv_profile.c \
+gdb_stdio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+src/stm32f4_timer.c
+
+FDMDV_PROFILE_SRCS += $(CODEC2_SRCS)
+
+fdmdv_profile.elf: $(FDMDV_PROFILE_SRCS)
+ $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
clean:
rm -f *.o
rm -f *.elf
--- /dev/null
+/*---------------------------------------------------------------------------*\\r
+\r
+ FILE........: codec2_profile.c\r
+ AUTHOR......: David Rowe\r
+ DATE CREATED: 30 May 2013\r
+\r
+ Profiling Codec 2 operation on the STM32F4.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+ Copyright (C) 2014 David Rowe\r
+\r
+ All rights reserved.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License version 2.1, as\r
+ published by the Free Software Foundation. This program is\r
+ distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\r
+ License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <math.h>\r
+\r
+#include "stm32f4xx_conf.h"\r
+#include "stm32f4xx.h"\r
+#include "gdb_stdio.h"\r
+#include "codec2.h"\r
+#include "dump.h"\r
+#include "sine.h"\r
+#include "machdep.h"\r
+\r
+#ifdef __EMBEDDED__\r
+#define printf gdb_stdio_printf\r
+#define fopen gdb_stdio_fopen\r
+#define fclose gdb_stdio_fclose\r
+#define fread gdb_stdio_fread\r
+#define fwrite gdb_stdio_fwrite\r
+#endif\r
+\r
+static void c2demo(int mode, char inputfile[], char outputfile[])\r
+{\r
+ struct CODEC2 *codec2;\r
+ short *inbuf, *outbuf;\r
+ unsigned char *bits;\r
+ int nsam, nbit;\r
+ FILE *fin, *fout;\r
+ int frame;\r
+ TIMER_VAR(enc_start, dec_start);\r
+\r
+ codec2 = codec2_create(mode);\r
+ nsam = codec2_samples_per_frame(codec2);\r
+ outbuf = (short*)malloc(nsam*sizeof(short));\r
+ inbuf = (short*)malloc(nsam*sizeof(short));\r
+ nbit = codec2_bits_per_frame(codec2);\r
+ bits = (unsigned char*)malloc(nbit*sizeof(char));\r
+\r
+ fin = fopen(inputfile, "rb");\r
+ if (fin == NULL) {\r
+ printf("Error opening input file: %s\n\nTerminating....\n",inputfile);\r
+ exit(1);\r
+ }\r
+\r
+ fout = fopen(outputfile, "wb");\r
+ if (fout == NULL) {\r
+ printf("Error opening output file: %s\n\nTerminating....\n",outputfile);\r
+ exit(1);\r
+ }\r
+\r
+ #ifdef DUMP\r
+ dump_on("stm32f4");\r
+ #endif\r
+ frame = 0;\r
+\r
+ while (fread(inbuf, sizeof(short), nsam, fin) == nsam) {\r
+ TIMER_SAMPLE(enc_start);\r
+ codec2_encode(codec2, bits, inbuf);\r
+ TIMER_SAMPLE_AND_LOG(dec_start, enc_start, " enc"); \r
+ codec2_decode(codec2, outbuf, bits);\r
+ TIMER_SAMPLE_AND_LOG2(dec_start, " dec"); \r
+ TIMER_SAMPLE_AND_LOG2(enc_start, " enc & dec"); \r
+ fwrite((char*)outbuf, sizeof(short), nsam, fout);\r
+ printf("frame: %d\n", ++frame);\r
+ machdep_timer_print_logged_samples();\r
+ }\r
+\r
+ #ifdef DUMP\r
+ dump_off("sm32f4");\r
+ #endif\r
+\r
+ fclose(fin);\r
+ fclose(fout);\r
+ free(inbuf);\r
+ free(outbuf);\r
+ free(bits);\r
+ codec2_destroy(codec2);\r
+}\r
+\r
+#define SPEED_TEST_SAMPLES 24000\r
+\r
+static void c2speedtest(int mode, char inputfile[])\r
+{\r
+ struct CODEC2 *codec2;\r
+ short *inbuf, *outbuf, *pinbuf;\r
+ unsigned char *bits;\r
+ int nsam, nbit, nframes;\r
+ FILE *fin;\r
+ int f, nread;\r
+\r
+ codec2 = codec2_create(mode);\r
+ nsam = codec2_samples_per_frame(codec2);\r
+ nframes = SPEED_TEST_SAMPLES/nsam;\r
+ outbuf = (short*)malloc(nsam*sizeof(short));\r
+ inbuf = (short*)malloc(SPEED_TEST_SAMPLES*sizeof(short));\r
+ nbit = codec2_bits_per_frame(codec2);\r
+ bits = (unsigned char*)malloc(nbit*sizeof(char));\r
+\r
+ fin = fopen(inputfile, "rb");\r
+ if (fin == NULL) {\r
+ printf("Error opening input file: %s\nTerminating....\n",inputfile);\r
+ exit(1);\r
+ }\r
+\r
+ nread = fread(inbuf, sizeof(short), SPEED_TEST_SAMPLES, fin);\r
+ if (nread != SPEED_TEST_SAMPLES) {\r
+ printf("error reading %s, %d samples reqd, %d read\n", \r
+ inputfile, SPEED_TEST_SAMPLES, nread);\r
+ }\r
+ fclose(fin);\r
+ \r
+ pinbuf = inbuf;\r
+ for(f=0; f<nframes; f++) {\r
+ GPIOD->ODR = (1 << 13);\r
+ codec2_encode(codec2, bits, pinbuf);\r
+ pinbuf += nsam;\r
+ GPIOD->ODR &= ~(1 << 13);\r
+ codec2_decode(codec2, outbuf, bits);\r
+ }\r
+\r
+ free(inbuf);\r
+ free(outbuf);\r
+ free(bits);\r
+ codec2_destroy(codec2);\r
+}\r
+\r
+void gpio_init() {\r
+ RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD \r
+ GPIOD->MODER = (1 << 26); // set pin 13 to be general \r
+ // purpose output\r
+}\r
+\r
+int main(int argc, char *argv[]) {\r
+ gpio_init();\r
+ machdep_timer_init ();\r
+ \r
+ printf("Starting c2demo\n");\r
+\r
+ /* File I/O test for profiling or (with #define DUMP)\r
+ dumping states for optimisation and tiuning */\r
+\r
+ c2demo(CODEC2_MODE_1600, "stm_in.raw", "stm_out.raw");\r
+\r
+ printf("Starting c2 speed test\n");\r
+ \r
+ /* Another test of execution speed. Look at PD13 with a\r
+ oscilliscope. On time is enc, off is dec */\r
+\r
+ c2speedtest(CODEC2_MODE_1600, "stm_in.raw");\r
+\r
+ printf("Finished\n");\r
+\r
+ return 0;\r
+}\r
+\r
--- /dev/null
+/*---------------------------------------------------------------------------*\\r
+\r
+ FILE........: fdmdv_profile.c\r
+ AUTHOR......: David Rowe\r
+ DATE CREATED: 18 July 2014\r
+\r
+ Profiling Codec 2 operation on the STM32F4.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+ Copyright (C) 2014 David Rowe\r
+\r
+ All rights reserved.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License version 2.1, as\r
+ published by the Free Software Foundation. This program is\r
+ distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\r
+ License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include <assert.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <math.h>\r
+\r
+#include "stm32f4xx_conf.h"\r
+#include "stm32f4xx.h"\r
+#include "gdb_stdio.h"\r
+#include "codec2_fdmdv.h"\r
+#include "dump.h"\r
+#include "sine.h"\r
+#include "machdep.h"\r
+\r
+#ifdef __EMBEDDED__\r
+#define printf gdb_stdio_printf\r
+#define fopen gdb_stdio_fopen\r
+#define fclose gdb_stdio_fclose\r
+#define fread gdb_stdio_fread\r
+#define fwrite gdb_stdio_fwrite\r
+#endif\r
+\r
+#define TEST_FRAMES 25\r
+\r
+int main(int argc, char *argv[]) {\r
+ struct FDMDV *fdmdv;\r
+ int bits_per_fdmdv_frame, bits_per_codec_frame;\r
+ int *tx_bits;\r
+ int *rx_bits;\r
+ COMP tx_fdm[2*FDMDV_NOM_SAMPLES_PER_FRAME];\r
+ int i, nin, reliable_sync_bit, sync_bit;\r
+ struct FDMDV_STATS stats;\r
+ TIMER_VAR(mod_start, demod_start);\r
+\r
+ fdmdv = fdmdv_create(FDMDV_NC);\r
+\r
+ bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);\r
+ bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);\r
+ tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(tx_bits != NULL);\r
+ rx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(rx_bits != NULL);\r
+\r
+ nin = FDMDV_NOM_SAMPLES_PER_FRAME;\r
+\r
+ for(i=0; i<TEST_FRAMES; i++) {\r
+ fdmdv_get_test_bits(fdmdv, tx_bits);\r
+ fdmdv_get_test_bits(fdmdv, &tx_bits[bits_per_fdmdv_frame]);\r
+\r
+ TIMER_SAMPLE(mod_start);\r
+\r
+ fdmdv_mod(fdmdv, tx_fdm, tx_bits, &sync_bit);\r
+ assert(sync_bit == 1);\r
+ fdmdv_mod(fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &tx_bits[bits_per_fdmdv_frame], &sync_bit);\r
+ assert(sync_bit == 0);\r
+\r
+ TIMER_SAMPLE_AND_LOG(demod_start, mod_start, " enc"); \r
+\r
+ fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit, tx_fdm, &nin);\r
+ fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &nin);\r
+ TIMER_SAMPLE_AND_LOG2(demod_start, " dec"); \r
+ TIMER_SAMPLE_AND_LOG2(mod_start, " enc & dec"); \r
+\r
+ fdmdv_get_demod_stats(fdmdv, &stats);\r
+ printf("frame: %d sync: %d reliable_sync_bit: %d SNR: %3.2f\n", i, stats.sync, reliable_sync_bit, (double)stats.snr_est);\r
+ machdep_timer_print_logged_samples();\r
+ }\r
+\r
+ fdmdv_destroy(fdmdv);\r
+\r
+ return 0;\r
+}\r
+\r
+++ /dev/null
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdint.h>\r
-#include <math.h>\r
-\r
-#include "stm32f4xx_conf.h"\r
-#include "stm32f4xx.h"\r
-#include "gdb_stdio.h"\r
-#include "codec2.h"\r
-#include "dump.h"\r
-#include "sine.h"\r
-#include "machdep.h"\r
-\r
-#ifdef __EMBEDDED__\r
-#define printf gdb_stdio_printf\r
-#define fopen gdb_stdio_fopen\r
-#define fclose gdb_stdio_fclose\r
-#define fread gdb_stdio_fread\r
-#define fwrite gdb_stdio_fwrite\r
-#endif\r
-\r
-static void c2demo(int mode, char inputfile[], char outputfile[])\r
-{\r
- struct CODEC2 *codec2;\r
- short *inbuf, *outbuf;\r
- unsigned char *bits;\r
- int nsam, nbit;\r
- FILE *fin, *fout;\r
- int frame;\r
- TIMER_VAR(enc_start, dec_start);\r
-\r
- codec2 = codec2_create(mode);\r
- nsam = codec2_samples_per_frame(codec2);\r
- outbuf = (short*)malloc(nsam*sizeof(short));\r
- inbuf = (short*)malloc(nsam*sizeof(short));\r
- nbit = codec2_bits_per_frame(codec2);\r
- bits = (unsigned char*)malloc(nbit*sizeof(char));\r
-\r
- fin = fopen(inputfile, "rb");\r
- if (fin == NULL) {\r
- printf("Error opening input file: %s\n\nTerminating....\n",inputfile);\r
- exit(1);\r
- }\r
-\r
- fout = fopen(outputfile, "wb");\r
- if (fout == NULL) {\r
- printf("Error opening output file: %s\n\nTerminating....\n",outputfile);\r
- exit(1);\r
- }\r
-\r
- #ifdef DUMP\r
- dump_on("stm32f4");\r
- #endif\r
- frame = 0;\r
-\r
- while (fread(inbuf, sizeof(short), nsam, fin) == nsam) {\r
- TIMER_SAMPLE(enc_start);\r
- codec2_encode(codec2, bits, inbuf);\r
- TIMER_SAMPLE_AND_LOG(dec_start, enc_start, " enc"); \r
- codec2_decode(codec2, outbuf, bits);\r
- TIMER_SAMPLE_AND_LOG2(dec_start, " dec"); \r
- TIMER_SAMPLE_AND_LOG2(enc_start, " enc & dec"); \r
- fwrite((char*)outbuf, sizeof(short), nsam, fout);\r
- printf("frame: %d\n", ++frame);\r
- machdep_timer_print_logged_samples();\r
- }\r
-\r
- #ifdef DUMP\r
- dump_off("sm32f4");\r
- #endif\r
-\r
- fclose(fin);\r
- fclose(fout);\r
- free(inbuf);\r
- free(outbuf);\r
- free(bits);\r
- codec2_destroy(codec2);\r
-}\r
-\r
-#define SPEED_TEST_SAMPLES 24000\r
-\r
-static void c2speedtest(int mode, char inputfile[])\r
-{\r
- struct CODEC2 *codec2;\r
- short *inbuf, *outbuf, *pinbuf;\r
- unsigned char *bits;\r
- int nsam, nbit, nframes;\r
- FILE *fin;\r
- int f, nread;\r
-\r
- codec2 = codec2_create(mode);\r
- nsam = codec2_samples_per_frame(codec2);\r
- nframes = SPEED_TEST_SAMPLES/nsam;\r
- outbuf = (short*)malloc(nsam*sizeof(short));\r
- inbuf = (short*)malloc(SPEED_TEST_SAMPLES*sizeof(short));\r
- nbit = codec2_bits_per_frame(codec2);\r
- bits = (unsigned char*)malloc(nbit*sizeof(char));\r
-\r
- fin = fopen(inputfile, "rb");\r
- if (fin == NULL) {\r
- printf("Error opening input file: %s\nTerminating....\n",inputfile);\r
- exit(1);\r
- }\r
-\r
- nread = fread(inbuf, sizeof(short), SPEED_TEST_SAMPLES, fin);\r
- if (nread != SPEED_TEST_SAMPLES) {\r
- printf("error reading %s, %d samples reqd, %d read\n", \r
- inputfile, SPEED_TEST_SAMPLES, nread);\r
- }\r
- fclose(fin);\r
- \r
- pinbuf = inbuf;\r
- for(f=0; f<nframes; f++) {\r
- GPIOD->ODR = (1 << 13);\r
- codec2_encode(codec2, bits, pinbuf);\r
- pinbuf += nsam;\r
- GPIOD->ODR &= ~(1 << 13);\r
- codec2_decode(codec2, outbuf, bits);\r
- }\r
-\r
- free(inbuf);\r
- free(outbuf);\r
- free(bits);\r
- codec2_destroy(codec2);\r
-}\r
-\r
-void gpio_init() {\r
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD \r
- GPIOD->MODER = (1 << 26); // set pin 13 to be general \r
- // purpose output\r
-}\r
-\r
-int main(int argc, char *argv[]) {\r
- SystemInit();\r
- gpio_init();\r
- machdep_timer_init ();\r
- \r
- printf("Starting c2demo\n");\r
-\r
- /* File I/O test for profiling or (with #define DUMP)\r
- dumping states for optimisation and tiuning */\r
-\r
- c2demo(CODEC2_MODE_1600, "stm_in.raw", "stm_out.raw");\r
-\r
- printf("Starting c2 speed test\n");\r
- \r
- /* Another test of execution speed. Look at PD13 with a\r
- oscilliscope. On time is enc, off is dec */\r
-\r
- c2speedtest(CODEC2_MODE_1600, "stm_in.raw");\r
-\r
- printf("Finished\n");\r
-\r
- return 0;\r
-}\r
-\r
unsigned int machdep_timer_sample_and_log(unsigned int start, char s[])
{
- char tmp[80];
+ char tmp[80];
+ float msec;
unsigned int dwt = *DWT_CYCCNT - start;
- sprintf(tmp, "%s %5.2f msecs\n",s,1000.0*(float)dwt/CORE_CLOCK);
+ msec = 1000.0*(float)dwt/CORE_CLOCK;
+ sprintf(tmp, "%s %5.2f msecs\n",s,(double)msec);
if ((strlen(buf) + strlen(tmp)) < BUF_SZ)
strcat(buf, tmp);
return *DWT_CYCCNT;
gdb_stdio_printf("%s", buf);
*buf = 0;
}
+