├── LICENSE ├── README.md ├── examples └── codec2-arduino │ └── codec2-arduino.ino ├── extras └── TEST700B.C2 ├── keywords.txt ├── library.properties └── src ├── codec2.h ├── codec2 ├── H2064_516_sparse.h ├── HRA_112_112.h ├── LICENSE ├── _kiss_fft_guts.h ├── ampexp.c ├── ampexp.h ├── bpf.h ├── bpfb.h ├── codebook.c ├── codebookd.c ├── codebookdt.c ├── codebookge.c ├── codebookjvm.c ├── codebooklspmelvq.c ├── codebookmel.c ├── codebooknewamp1_energy.c ├── codebookres.c ├── codebookvq.c ├── codec2.c ├── codec2_cohpsk.h ├── codec2_fdmdv.h ├── codec2_fft.c ├── codec2_fft.h ├── codec2_fifo.h ├── codec2_fm.h ├── codec2_internal.h ├── codec2_ofdm.h ├── cohpsk.c ├── cohpsk_defs.h ├── cohpsk_internal.h ├── comp.h ├── comp_prim.h ├── defines.h ├── dump.c ├── dump.h ├── fdmdv.c ├── fdmdv_internal.h ├── fifo.c ├── fm.c ├── fm_fir_coeff.h ├── fmfsk.c ├── fmfsk.h ├── freedv_api.c ├── freedv_api.h ├── freedv_api_internal.h ├── freedv_data_channel.c ├── freedv_data_channel.h ├── freedv_vhf_framing.c ├── freedv_vhf_framing.h ├── fsk.c ├── fsk.h ├── golay23.c ├── golay23.h ├── golaydectable.h ├── golayenctable.h ├── hanning.h ├── horus_l2.c ├── horus_l2.h ├── ht_coeff.h ├── interp.c ├── interp.h ├── kiss_fft.c ├── kiss_fft.h ├── kiss_fftr.c ├── kiss_fftr.h ├── linreg.c ├── linreg.h ├── lpc.c ├── lpc.h ├── lsp.c ├── lsp.h ├── machdep.h ├── mbest.c ├── mbest.h ├── modem_probe.c ├── modem_probe.h ├── modem_stats.c ├── modem_stats.h ├── mpdecode_core.c ├── mpdecode_core.h ├── nlp.c ├── nlp.h ├── noise_samples.h ├── octave.c ├── octave.h ├── ofdm.c ├── ofdm_internal.h ├── os.h ├── pack.c ├── phase.c ├── phase.h ├── phaseexp.h ├── pilot_coeff.h ├── pilots_coh.h ├── postfilter.c ├── postfilter.h ├── quantise.c ├── quantise.h ├── rn.h ├── rn_coh.h ├── rxdec_coeff.h ├── sine.c ├── sine.h ├── ssbfilt_coeff.h ├── tdma.h ├── test.h ├── test_bits.h ├── test_bits_coh.h ├── test_bits_ofdm.h ├── varicode.c ├── varicode.h └── varicode_table.h └── libsamplerate ├── LICENSE ├── common.h ├── config.h ├── fastest_coeffs.h ├── float_cast.h ├── high_qual_coeffs.h ├── mid_qual_coeffs.h ├── samplerate.c ├── samplerate.h ├── src_linear.c ├── src_sinc.c └── src_zoh.c /README.md: -------------------------------------------------------------------------------- 1 | # codec2-arduino 2 | 3 | This is a proof-of-concept for using the [Codec2 audio codec library](http://www.rowetel.com/?page_id=452) on the Arduino-compatible [Adafruit Feather nRF52 Bluefruit LE board](https://www.adafruit.com/product/3406). The nRF52 contains a Cortex M4F processor, which is the same one used in the [SM1000](http://www.rowetel.com/?page_id=3902). The SM1000 is a device that encodes and decodes Codec2 audio. It is meant to be used in conjunction with a radio to send and receive voice communications. 4 | 5 | Now that Adafruit is providing a convenient Arduino-compatible board with the same processor, I wanted to see if I could get Codec2 to compile inside of the Arduino IDE. It worked! 6 | 7 | ## Getting Started 8 | 9 | This is just a proof-of-concept. It contains the following components: 10 | 11 | 1. Codec2 source - all of the .h and .c files are included here. The build system is not used. 12 | 3. libsamplerate - Required by Codec2. All of the .h and .c files are included here 13 | 4. codec2-arduino.ino - An example application 14 | 15 | ### Prerequisites 16 | 17 | You will need an [Adafruit Feather nRF52 Bluefruit LE board](https://www.adafruit.com/product/3406). 18 | The current demo also requires a [Adalogger FeatherWing - RTC + SD Add-on](https://www.adafruit.com/product/2922) and an SD card. 19 | 20 | You will also need a USB micro-B cable to program the nRF52 board and some way to write to the SD card from your computer. 21 | 22 | ### Installing 23 | 24 | Install the Codec2 library using the Library Manager in the Arduino IDE. 25 | 26 | Open the example application using the Examples -> Codec2 menu. 27 | 28 | Format the SD card to use FAT32. 29 | 30 | For testing, you will need a Codec2 file using mode 700B. You can find one in the extras/ directory. Place this on the SD card in the root directory. It must be named TEST700B.C2. 31 | 32 | Place the SD card in the Adalogger. 33 | 34 | Follow the [Adafruit tutorial](https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide) to get your nRF52 board set up. 35 | 36 | Open the example application using the Sketchbook -> Examples menu. 37 | 38 | Connect the USB micro-B cable to the nRF52 board and hit the Upload button. 39 | 40 | ## Testing 41 | 42 | Click the Serial Monitor button in the Arduino IDE. 43 | If all is going well, you should see lots of unreadable gibberish on your screen. 44 | Congratulations, this is successfully decoded audio! 45 | 46 | ## Contributing 47 | 48 | This is just a proof of concept. Better examples would be great to have. If you would be interested in working on that, let me know. 49 | 50 | ## Authors 51 | 52 | * **Dr. Brandon Wiley** - *Initial concept* - [Operator Foundation](https://OperatorFoundation.org/) 53 | 54 | ## License 55 | 56 | The codec2-arduino sketch is licensed under the GPL v3.0 license - see the [LICENSE.md](LICENSE.md) file for details 57 | 58 | Codec2 is licensed under the LGPL v2.1 license 59 | 60 | libsamplerate is licensed under the 2-clause BSD license 61 | 62 | ## Acknowledgments 63 | 64 | * Thanks to all the folks on the #codec2 IRC channel for helping me figure out how to get everything to compile. 65 | -------------------------------------------------------------------------------- /examples/codec2-arduino/codec2-arduino.ino: -------------------------------------------------------------------------------- 1 | #include "codec2.h" 2 | 3 | //#define TESTING 4 | 5 | #define STORAGE_CAPABLE 6 | 7 | #ifdef STORAGE_CAPABLE 8 | #include 9 | 10 | Sd2Card card; 11 | SdVolume volume; 12 | SdFile root; 13 | 14 | // M0 feather with SD wing 15 | // #define SD_CS 10 16 | // Adalogger SD 17 | // #define SD_CS 4 18 | // nRF52 feather with SD wing 19 | #define SD_CS 11 20 | #endif 21 | 22 | bool storageReady=false; 23 | 24 | const int mode=CODEC2_MODE_700B; 25 | const int natural=1; 26 | 27 | CODEC2 *codec2; 28 | int nsam, nbit, nbyte, i, frames, bits_proc, bit_errors, error_mode; 29 | int nstart_bit, nend_bit, bit_rate; 30 | short *buf; 31 | unsigned char *bits; 32 | float *softdec_bits; 33 | 34 | void setup() 35 | { 36 | Serial.begin(19200); 37 | 38 | unsigned long startTime=millis(); 39 | while(!Serial && (startTime+(10*1000) > millis())) {} 40 | 41 | #ifdef STORAGE_CAPABLE 42 | // we'll use the initialization code from the utility libraries 43 | // since we're just testing if the card is working! 44 | if (!card.init(SPI_HALF_SPEED, SD_CS)) { 45 | storageReady=false; 46 | #ifdef TESTING 47 | Serial.println("SD not found"); 48 | Serial.println("storage disabled"); 49 | #endif 50 | } else { 51 | #ifdef TESTING 52 | Serial.println("SD card wiring is correct and a card is present."); 53 | 54 | // print the type of card 55 | Serial.print("\nCard type: "); 56 | switch (card.type()) { 57 | case SD_CARD_TYPE_SD1: 58 | Serial.println("SD1"); 59 | break; 60 | case SD_CARD_TYPE_SD2: 61 | Serial.println("SD2"); 62 | break; 63 | case SD_CARD_TYPE_SDHC: 64 | Serial.println("SDHC"); 65 | break; 66 | default: 67 | Serial.println("Unknown"); 68 | } 69 | #endif 70 | 71 | if(volume.init(card)) 72 | { 73 | uint32_t volumesize; 74 | #ifdef TESTING 75 | Serial.print("\nVolume type is FAT"); 76 | Serial.println(volume.fatType(), DEC); 77 | Serial.println(); 78 | #endif 79 | 80 | storageReady=true; 81 | #ifdef TESTING 82 | Serial.println("storage enabled"); 83 | 84 | volumesize = volume.blocksPerCluster(); // clusters are collections of blocks 85 | volumesize *= volume.clusterCount(); // we'll have a lot of clusters 86 | volumesize *= 512; // SD card blocks are always 512 bytes 87 | Serial.print("Volume size (bytes): "); 88 | Serial.println(volumesize); 89 | Serial.print("Volume size (Kbytes): "); 90 | volumesize /= 1024; 91 | Serial.println(volumesize); 92 | Serial.print("Volume size (Mbytes): "); 93 | volumesize /= 1024; 94 | Serial.println(volumesize); 95 | 96 | Serial.println("\nFiles found on the card (name, date and size in bytes): "); 97 | #endif 98 | 99 | root.openRoot(volume); 100 | 101 | // list all files in the card with date and size 102 | #ifdef TESTING 103 | root.ls(LS_R | LS_DATE | LS_SIZE); 104 | #endif 105 | } 106 | else 107 | { 108 | Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); 109 | storageReady=false; 110 | Serial.println("storage disbled"); 111 | } 112 | } 113 | #endif 114 | 115 | codec2 = codec2_create(mode); 116 | nsam = codec2_samples_per_frame(codec2); 117 | nbit = codec2_bits_per_frame(codec2); 118 | buf = (short*)malloc(nsam*sizeof(short)); 119 | nbyte = (nbit + 7) / 8; 120 | bits = (unsigned char*)malloc(nbyte*sizeof(char)); 121 | softdec_bits = (float*)malloc(nbit*sizeof(float)); 122 | frames = bit_errors = bits_proc = 0; 123 | nstart_bit = 0; 124 | nend_bit = nbit-1; 125 | 126 | codec2_set_natural_or_gray(codec2, !natural); 127 | 128 | if(storageReady) 129 | { 130 | recitation(); 131 | } 132 | 133 | codec2_destroy(codec2); 134 | } 135 | 136 | void loop() 137 | { 138 | } 139 | 140 | void recitation() 141 | { 142 | #ifdef TESTING 143 | Serial.println("Begin recitation"); 144 | #endif 145 | uint8_t c2Buf[nbyte]; 146 | uint8_t maxlen = sizeof(c2Buf); 147 | uint8_t offset=0; 148 | 149 | int16_t audioBuf[nsam]; 150 | 151 | SD.begin(SD_CS); 152 | File c2File = SD.open("TEST700B.C2"); 153 | if (c2File) { 154 | #ifdef TESTING 155 | Serial.println("Reciting Codec2 file"); 156 | #endif 157 | 158 | // read from the file until there's nothing else in it: 159 | while (c2File.available()) { 160 | #ifdef TESTING 161 | Serial.print("~"); 162 | #endif 163 | 164 | offset=0; 165 | for(int x=0; x> 8; 188 | Serial.print(lo); 189 | Serial.print(hi); 190 | } 191 | } 192 | 193 | // close the file: 194 | c2File.close(); 195 | #ifdef TESTING 196 | Serial.println("Recitation complete."); 197 | #endif 198 | } else { 199 | // if the file didn't open, print an error: 200 | Serial.println("Error opening Codec2 file"); 201 | } 202 | } 203 | 204 | -------------------------------------------------------------------------------- /extras/TEST700B.C2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blanu/codec2-arduino/edf541f9ee93ed165758a5704a75c49b2fc8df66/extras/TEST700B.C2 -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For codec2-arduino 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | CODEC2 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | codec2_create KEYWORD2 16 | codec2_destroy KEYWORD2 17 | codec2_encode KEYWORD2 18 | codec2_decode KEYWORD2 19 | codec2_samples_per_frame KEYWORD2 20 | codec2_bits_per_frame KEYWORD2 21 | 22 | ####################################### 23 | # Instances (KEYWORD2) 24 | ####################################### 25 | 26 | ####################################### 27 | # Constants (LITERAL1) 28 | ####################################### 29 | 30 | CODEC2_MODE_3200 LITERAL1 31 | CODEC2_MODE_2400 LITERAL1 32 | CODEC2_MODE_1600 LITERAL1 33 | CODEC2_MODE_1400 LITERAL1 34 | CODEC2_MODE_1300 LITERAL1 35 | CODEC2_MODE_1200 LITERAL1 36 | CODEC2_MODE_700 LITERAL1 37 | CODEC2_MODE_700B LITERAL1 38 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Codec2 2 | version=1.0.0 3 | author=Dr. Brandon Wiley 4 | maintainer=Dr. Brandon Wiley 5 | sentence=The Codec2 library is a proof-of-concept for running the Codec2 audio codec on an Arduino-compatible Adafruit Feather nRF52 Bluefruit LE board. 6 | paragraph=Codec2 is an open source speech codec designed for communications quality speech between 700bps and 3200bps. The main application is low bandwidth HF/VHF digital radio. It fills a gap in open source voice codecs beneath 5000bps. 7 | category=Communication 8 | url=https://github.com/blanu/codec2-arduino 9 | architectures=nrf52 10 | includes=codec2.h 11 | -------------------------------------------------------------------------------- /src/codec2.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 21 August 2010 6 | 7 | Codec 2 fully quantised encoder and decoder functions. If you want use 8 | Codec 2, these are the functions you need to call. 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright (C) 2010 David Rowe 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | */ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #ifndef __CODEC2__ 34 | #define __CODEC2__ 35 | 36 | #define CODEC2_MODE_3200 0 37 | #define CODEC2_MODE_2400 1 38 | #define CODEC2_MODE_1600 2 39 | #define CODEC2_MODE_1400 3 40 | #define CODEC2_MODE_1300 4 41 | #define CODEC2_MODE_1200 5 42 | #define CODEC2_MODE_700 6 43 | #define CODEC2_MODE_700B 7 44 | #define CODEC2_MODE_700C 8 45 | 46 | struct CODEC2; 47 | 48 | struct CODEC2 * codec2_create(int mode); 49 | void codec2_destroy(struct CODEC2 *codec2_state); 50 | void codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]); 51 | void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits); 52 | void codec2_decode_ber(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits, float ber_est); 53 | int codec2_samples_per_frame(struct CODEC2 *codec2_state); 54 | int codec2_bits_per_frame(struct CODEC2 *codec2_state); 55 | 56 | void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma); 57 | int codec2_get_spare_bit_index(struct CODEC2 *codec2_state); 58 | int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); 59 | void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); 60 | void codec2_set_softdec(struct CODEC2 *c2, float *softdec); 61 | float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); 62 | 63 | 64 | #endif 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /src/codec2/ampexp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: ampexp.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: & August 2012 6 | 7 | Functions for experimenting with amplitude quantisation. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2012 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not,see . 26 | */ 27 | 28 | #ifndef __AMPEX__ 29 | #define __AMPEXP__ 30 | 31 | #include "defines.h" 32 | 33 | struct AEXP; 34 | 35 | struct AEXP *amp_experiment_create(); 36 | void amp_experiment_destroy(struct AEXP *aexp); 37 | void amp_experiment(struct AEXP *aexp, MODEL *model, char *arg); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/codec2/bpf.h: -------------------------------------------------------------------------------- 1 | #define BPF_N 101 2 | 3 | float bpf[]={ 4 | 0.002174, 5 | 0.003245, 6 | 0.002147, 7 | 0.001866, 8 | 0.002764, 9 | 0.000567, 10 | -0.001641, 11 | -0.000565, 12 | -0.002415, 13 | -0.005837, 14 | -0.003620, 15 | -0.002828, 16 | -0.006268, 17 | -0.002787, 18 | 0.001963, 19 | -0.001234, 20 | 0.001446, 21 | 0.009200, 22 | 0.005331, 23 | 0.003521, 24 | 0.011821, 25 | 0.006951, 26 | -0.002015, 27 | 0.005137, 28 | 0.001828, 29 | -0.013390, 30 | -0.007058, 31 | -0.003273, 32 | -0.020458, 33 | -0.014321, 34 | 0.001751, 35 | -0.012891, 36 | -0.009730, 37 | 0.018993, 38 | 0.008544, 39 | 0.000534, 40 | 0.035755, 41 | 0.029074, 42 | -0.001192, 43 | 0.030852, 44 | 0.030983, 45 | -0.029834, 46 | -0.009550, 47 | 0.011945, 48 | -0.081971, 49 | -0.082875, 50 | 0.000423, 51 | -0.133526, 52 | -0.211778, 53 | 0.182628, 54 | 0.514906, 55 | 0.182628, 56 | -0.211778, 57 | -0.133526, 58 | 0.000423, 59 | -0.082875, 60 | -0.081971, 61 | 0.011945, 62 | -0.009550, 63 | -0.029834, 64 | 0.030983, 65 | 0.030852, 66 | -0.001192, 67 | 0.029074, 68 | 0.035755, 69 | 0.000534, 70 | 0.008544, 71 | 0.018993, 72 | -0.009730, 73 | -0.012891, 74 | 0.001751, 75 | -0.014321, 76 | -0.020458, 77 | -0.003273, 78 | -0.007058, 79 | -0.013390, 80 | 0.001828, 81 | 0.005137, 82 | -0.002015, 83 | 0.006951, 84 | 0.011821, 85 | 0.003521, 86 | 0.005331, 87 | 0.009200, 88 | 0.001446, 89 | -0.001234, 90 | 0.001963, 91 | -0.002787, 92 | -0.006268, 93 | -0.002828, 94 | -0.003620, 95 | -0.005837, 96 | -0.002415, 97 | -0.000565, 98 | -0.001641, 99 | 0.000567, 100 | 0.002764, 101 | 0.001866, 102 | 0.002147, 103 | 0.003245, 104 | 0.002174 105 | }; 106 | 107 | -------------------------------------------------------------------------------- /src/codec2/bpfb.h: -------------------------------------------------------------------------------- 1 | #define BPFB_N 101 2 | 3 | float bpfb[]={ 4 | 0.003795, 5 | 0.006827, 6 | 0.002261, 7 | 0.002523, 8 | 0.005758, 9 | -0.000264, 10 | -0.000674, 11 | 0.003113, 12 | -0.004144, 13 | -0.004923, 14 | 0.000043, 15 | -0.008017, 16 | -0.008711, 17 | -0.001802, 18 | -0.010210, 19 | -0.010428, 20 | -0.000899, 21 | -0.009413, 22 | -0.009072, 23 | 0.003469, 24 | -0.005335, 25 | -0.004828, 26 | 0.010724, 27 | 0.000941, 28 | 0.000708, 29 | 0.018957, 30 | 0.007084, 31 | 0.004825, 32 | 0.025418, 33 | 0.010147, 34 | 0.004452, 35 | 0.027434, 36 | 0.007550, 37 | -0.002861, 38 | 0.023483, 39 | -0.001944, 40 | -0.018138, 41 | 0.014122, 42 | -0.017583, 43 | -0.040768, 44 | 0.002598, 45 | -0.036604, 46 | -0.069541, 47 | -0.004273, 48 | -0.054876, 49 | -0.107289, 50 | 0.010068, 51 | -0.068052, 52 | -0.200119, 53 | 0.207287, 54 | 0.597150, 55 | 0.207287, 56 | -0.200119, 57 | -0.068052, 58 | 0.010068, 59 | -0.107289, 60 | -0.054876, 61 | -0.004273, 62 | -0.069541, 63 | -0.036604, 64 | 0.002598, 65 | -0.040768, 66 | -0.017583, 67 | 0.014122, 68 | -0.018138, 69 | -0.001944, 70 | 0.023483, 71 | -0.002861, 72 | 0.007550, 73 | 0.027434, 74 | 0.004452, 75 | 0.010147, 76 | 0.025418, 77 | 0.004825, 78 | 0.007084, 79 | 0.018957, 80 | 0.000708, 81 | 0.000941, 82 | 0.010724, 83 | -0.004828, 84 | -0.005335, 85 | 0.003469, 86 | -0.009072, 87 | -0.009413, 88 | -0.000899, 89 | -0.010428, 90 | -0.010210, 91 | -0.001802, 92 | -0.008711, 93 | -0.008017, 94 | 0.000043, 95 | -0.004923, 96 | -0.004144, 97 | 0.003113, 98 | -0.000674, 99 | -0.000264, 100 | 0.005758, 101 | 0.002523, 102 | 0.002261, 103 | 0.006827, 104 | 0.003795 105 | }; -------------------------------------------------------------------------------- /src/codec2/codebook.c: -------------------------------------------------------------------------------- 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ 2 | 3 | /* 4 | * This intermediary file and the files that used to create it are under 5 | * The LGPL. See the file COPYING. 6 | */ 7 | 8 | #include "defines.h" 9 | 10 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp1.txt */ 11 | static const float codes0[] = { 12 | 225, 13 | 250, 14 | 275, 15 | 300, 16 | 325, 17 | 350, 18 | 375, 19 | 400, 20 | 425, 21 | 450, 22 | 475, 23 | 500, 24 | 525, 25 | 550, 26 | 575, 27 | 600 28 | }; 29 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp2.txt */ 30 | static const float codes1[] = { 31 | 325, 32 | 350, 33 | 375, 34 | 400, 35 | 425, 36 | 450, 37 | 475, 38 | 500, 39 | 525, 40 | 550, 41 | 575, 42 | 600, 43 | 625, 44 | 650, 45 | 675, 46 | 700 47 | }; 48 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp3.txt */ 49 | static const float codes2[] = { 50 | 500, 51 | 550, 52 | 600, 53 | 650, 54 | 700, 55 | 750, 56 | 800, 57 | 850, 58 | 900, 59 | 950, 60 | 1000, 61 | 1050, 62 | 1100, 63 | 1150, 64 | 1200, 65 | 1250 66 | }; 67 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp4.txt */ 68 | static const float codes3[] = { 69 | 700, 70 | 800, 71 | 900, 72 | 1000, 73 | 1100, 74 | 1200, 75 | 1300, 76 | 1400, 77 | 1500, 78 | 1600, 79 | 1700, 80 | 1800, 81 | 1900, 82 | 2000, 83 | 2100, 84 | 2200 85 | }; 86 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp5.txt */ 87 | static const float codes4[] = { 88 | 950, 89 | 1050, 90 | 1150, 91 | 1250, 92 | 1350, 93 | 1450, 94 | 1550, 95 | 1650, 96 | 1750, 97 | 1850, 98 | 1950, 99 | 2050, 100 | 2150, 101 | 2250, 102 | 2350, 103 | 2450 104 | }; 105 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp6.txt */ 106 | static const float codes5[] = { 107 | 1100, 108 | 1200, 109 | 1300, 110 | 1400, 111 | 1500, 112 | 1600, 113 | 1700, 114 | 1800, 115 | 1900, 116 | 2000, 117 | 2100, 118 | 2200, 119 | 2300, 120 | 2400, 121 | 2500, 122 | 2600 123 | }; 124 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp7.txt */ 125 | static const float codes6[] = { 126 | 1500, 127 | 1600, 128 | 1700, 129 | 1800, 130 | 1900, 131 | 2000, 132 | 2100, 133 | 2200, 134 | 2300, 135 | 2400, 136 | 2500, 137 | 2600, 138 | 2700, 139 | 2800, 140 | 2900, 141 | 3000 142 | }; 143 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp8.txt */ 144 | static const float codes7[] = { 145 | 2300, 146 | 2400, 147 | 2500, 148 | 2600, 149 | 2700, 150 | 2800, 151 | 2900, 152 | 3000 153 | }; 154 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp9.txt */ 155 | static const float codes8[] = { 156 | 2500, 157 | 2600, 158 | 2700, 159 | 2800, 160 | 2900, 161 | 3000, 162 | 3100, 163 | 3200 164 | }; 165 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp10.txt */ 166 | static const float codes9[] = { 167 | 2900, 168 | 3100, 169 | 3300, 170 | 3500 171 | }; 172 | 173 | const struct lsp_codebook lsp_cb[] = { 174 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp1.txt */ 175 | { 176 | 1, 177 | 4, 178 | 16, 179 | codes0 180 | }, 181 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp2.txt */ 182 | { 183 | 1, 184 | 4, 185 | 16, 186 | codes1 187 | }, 188 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp3.txt */ 189 | { 190 | 1, 191 | 4, 192 | 16, 193 | codes2 194 | }, 195 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp4.txt */ 196 | { 197 | 1, 198 | 4, 199 | 16, 200 | codes3 201 | }, 202 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp5.txt */ 203 | { 204 | 1, 205 | 4, 206 | 16, 207 | codes4 208 | }, 209 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp6.txt */ 210 | { 211 | 1, 212 | 4, 213 | 16, 214 | codes5 215 | }, 216 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp7.txt */ 217 | { 218 | 1, 219 | 4, 220 | 16, 221 | codes6 222 | }, 223 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp8.txt */ 224 | { 225 | 1, 226 | 3, 227 | 8, 228 | codes7 229 | }, 230 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp9.txt */ 231 | { 232 | 1, 233 | 3, 234 | 8, 235 | codes8 236 | }, 237 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/lsp10.txt */ 238 | { 239 | 1, 240 | 2, 241 | 4, 242 | codes9 243 | }, 244 | { 0, 0, 0, 0 } 245 | }; 246 | -------------------------------------------------------------------------------- /src/codec2/codebookdt.c: -------------------------------------------------------------------------------- 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ 2 | 3 | /* 4 | * This intermediary file and the files that used to create it are under 5 | * The LGPL. See the file COPYING. 6 | */ 7 | 8 | #include "defines.h" 9 | 10 | /* codebook/lspdt1.txt */ 11 | static const float codes0[] = { 12 | -75, 13 | -50, 14 | -25, 15 | 0, 16 | 25, 17 | 50, 18 | 75, 19 | 100 20 | }; 21 | /* codebook/lspdt2.txt */ 22 | static const float codes1[] = { 23 | -75, 24 | -50, 25 | -25, 26 | 0, 27 | 25, 28 | 50, 29 | 75, 30 | 100 31 | }; 32 | /* codebook/lspdt3.txt */ 33 | static const float codes2[] = { 34 | -50, 35 | 0, 36 | 50, 37 | 100 38 | }; 39 | /* codebook/lspdt4.txt */ 40 | static const float codes3[] = { 41 | -50, 42 | 0, 43 | 50, 44 | 100 45 | }; 46 | /* codebook/lspdt5.txt */ 47 | static const float codes4[] = { 48 | -50, 49 | 0, 50 | 50, 51 | 100 52 | }; 53 | /* codebook/lspdt6.txt */ 54 | static const float codes5[] = { 55 | -50, 56 | 0, 57 | 50, 58 | 100 59 | }; 60 | /* codebook/lspdt7.txt */ 61 | static const float codes6[] = { 62 | -50, 63 | 50 64 | }; 65 | /* codebook/lspdt8.txt */ 66 | static const float codes7[] = { 67 | -50, 68 | 50 69 | }; 70 | /* codebook/lspdt9.txt */ 71 | static const float codes8[] = { 72 | -50, 73 | 50 74 | }; 75 | /* codebook/lspdt10.txt */ 76 | static const float codes9[] = { 77 | -50, 78 | 50 79 | }; 80 | 81 | const struct lsp_codebook lsp_cbdt[] = { 82 | /* codebook/lspdt1.txt */ 83 | { 84 | 1, 85 | 3, 86 | 8, 87 | codes0 88 | }, 89 | /* codebook/lspdt2.txt */ 90 | { 91 | 1, 92 | 3, 93 | 8, 94 | codes1 95 | }, 96 | /* codebook/lspdt3.txt */ 97 | { 98 | 1, 99 | 2, 100 | 4, 101 | codes2 102 | }, 103 | /* codebook/lspdt4.txt */ 104 | { 105 | 1, 106 | 2, 107 | 4, 108 | codes3 109 | }, 110 | /* codebook/lspdt5.txt */ 111 | { 112 | 1, 113 | 2, 114 | 4, 115 | codes4 116 | }, 117 | /* codebook/lspdt6.txt */ 118 | { 119 | 1, 120 | 2, 121 | 4, 122 | codes5 123 | }, 124 | /* codebook/lspdt7.txt */ 125 | { 126 | 1, 127 | 1, 128 | 2, 129 | codes6 130 | }, 131 | /* codebook/lspdt8.txt */ 132 | { 133 | 1, 134 | 1, 135 | 2, 136 | codes7 137 | }, 138 | /* codebook/lspdt9.txt */ 139 | { 140 | 1, 141 | 1, 142 | 2, 143 | codes8 144 | }, 145 | /* codebook/lspdt10.txt */ 146 | { 147 | 1, 148 | 1, 149 | 2, 150 | codes9 151 | }, 152 | { 0, 0, 0, 0 } 153 | }; 154 | -------------------------------------------------------------------------------- /src/codec2/codebookmel.c: -------------------------------------------------------------------------------- 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ 2 | 3 | /* 4 | * This intermediary file and the files that used to create it are under 5 | * The LGPL. See the file COPYING. 6 | */ 7 | 8 | #include "defines.h" 9 | 10 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel1.txt */ 11 | static const float codes0[] = { 12 | 550, 13 | 600, 14 | 650, 15 | 700, 16 | 750, 17 | 800, 18 | 850, 19 | 900 20 | }; 21 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel2.txt */ 22 | static const float codes1[] = { 23 | 50, 24 | 100, 25 | 200, 26 | 300 27 | }; 28 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel3.txt */ 29 | static const float codes2[] = { 30 | 800, 31 | 850, 32 | 900, 33 | 950, 34 | 1000, 35 | 1050, 36 | 1100, 37 | 1150, 38 | 1200, 39 | 1250, 40 | 1300, 41 | 1350, 42 | 1400, 43 | 1450, 44 | 1500, 45 | 1650 46 | }; 47 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel4.txt */ 48 | static const float codes3[] = { 49 | 25, 50 | 50, 51 | 75, 52 | 100, 53 | 125, 54 | 150, 55 | 175, 56 | 250 57 | }; 58 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel5.txt */ 59 | static const float codes4[] = { 60 | 1350, 61 | 1400, 62 | 1450, 63 | 1500, 64 | 1550, 65 | 1600, 66 | 1650, 67 | 1700 68 | }; 69 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel6.txt */ 70 | static const float codes5[] = { 71 | 25, 72 | 50, 73 | 100, 74 | 150 75 | }; 76 | 77 | const struct lsp_codebook mel_cb[] = { 78 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel1.txt */ 79 | { 80 | 1, 81 | 3, 82 | 8, 83 | codes0 84 | }, 85 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel2.txt */ 86 | { 87 | 1, 88 | 2, 89 | 4, 90 | codes1 91 | }, 92 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel3.txt */ 93 | { 94 | 1, 95 | 4, 96 | 16, 97 | codes2 98 | }, 99 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel4.txt */ 100 | { 101 | 1, 102 | 3, 103 | 8, 104 | codes3 105 | }, 106 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel5.txt */ 107 | { 108 | 1, 109 | 3, 110 | 8, 111 | codes4 112 | }, 113 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/mel6.txt */ 114 | { 115 | 1, 116 | 2, 117 | 4, 118 | codes5 119 | }, 120 | { 0, 0, 0, 0 } 121 | }; 122 | -------------------------------------------------------------------------------- /src/codec2/codebooknewamp1_energy.c: -------------------------------------------------------------------------------- 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ 2 | 3 | /* 4 | * This intermediary file and the files that used to create it are under 5 | * The LGPL. See the file COPYING. 6 | */ 7 | 8 | #include "defines.h" 9 | 10 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/newamp1_energy_q.txt */ 11 | static const float codes0[] = { 12 | 10, 13 | 12.5, 14 | 15, 15 | 17.5, 16 | 20, 17 | 22.5, 18 | 25, 19 | 27.5, 20 | 30, 21 | 32.5, 22 | 35, 23 | 37.5, 24 | 40, 25 | 42.5, 26 | 45, 27 | 47.5 28 | }; 29 | 30 | const struct lsp_codebook newamp1_energy_cb[] = { 31 | /* /Users/brandon/freetel-code/codec2/branches/0.6/src/codebook/newamp1_energy_q.txt */ 32 | { 33 | 1, 34 | 4, 35 | 16, 36 | codes0 37 | }, 38 | { 0, 0, 0, 0 } 39 | }; 40 | -------------------------------------------------------------------------------- /src/codec2/codebookres.c: -------------------------------------------------------------------------------- 1 | /* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */ 2 | 3 | /* 4 | * This intermediary file and the files that used to create it are under 5 | * The LGPL. See the file COPYING. 6 | */ 7 | 8 | #include "defines.h" 9 | 10 | /* ../src/codebook/lspres_centre1.txt */ 11 | static const float codes0[] = { 12 | 300, 13 | 350, 14 | 400, 15 | 450, 16 | 500, 17 | 550, 18 | 600, 19 | 650 20 | }; 21 | /* ../src/codebook/lspres_bw1.txt */ 22 | static const float codes1[] = { 23 | 35, 24 | 80, 25 | 140, 26 | 250 27 | }; 28 | /* ../src/codebook/lsp3.txt */ 29 | static const float codes2[] = { 30 | 500, 31 | 550, 32 | 600, 33 | 650, 34 | 700, 35 | 750, 36 | 800, 37 | 850, 38 | 900, 39 | 950, 40 | 1000, 41 | 1050, 42 | 1100, 43 | 1150, 44 | 1200, 45 | 1250 46 | }; 47 | /* ../src/codebook/lsp4.txt */ 48 | static const float codes3[] = { 49 | 700, 50 | 800, 51 | 900, 52 | 1000, 53 | 1100, 54 | 1200, 55 | 1300, 56 | 1400, 57 | 1500, 58 | 1600, 59 | 1700, 60 | 1800, 61 | 1900, 62 | 2000, 63 | 2100, 64 | 2200 65 | }; 66 | 67 | const struct lsp_codebook lsp_cbres[] = { 68 | /* ../src/codebook/lspres_centre1.txt */ 69 | { 70 | 1, 71 | 3, 72 | 8, 73 | codes0 74 | }, 75 | /* ../src/codebook/lspres_bw1.txt */ 76 | { 77 | 1, 78 | 2, 79 | 4, 80 | codes1 81 | }, 82 | /* ../src/codebook/lsp3.txt */ 83 | { 84 | 1, 85 | 4, 86 | 16, 87 | codes2 88 | }, 89 | /* ../src/codebook/lsp4.txt */ 90 | { 91 | 1, 92 | 4, 93 | 16, 94 | codes3 95 | }, 96 | { 0, 0, 0, 0 } 97 | }; 98 | -------------------------------------------------------------------------------- /src/codec2/codec2_cohpsk.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_cohpsk.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: March 2015 6 | 7 | Functions that implement a coherent PSK FDM modem. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2015 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __CODEC2_COHPSK__ 29 | #define __CODEC2_COHPSK__ 30 | 31 | #define COHPSK_BITS_PER_FRAME 56 /* hard coded for now */ 32 | #define COHPSK_NC 7 /* hard coded for now */ 33 | #define COHPSK_NOM_SAMPLES_PER_FRAME 600 34 | #define COHPSK_MAX_SAMPLES_PER_FRAME 625 35 | #define COHPSK_RS 75 36 | #define COHPSK_FS 7500 /* note this is a wierd 37 | value to get an integer 38 | oversampling rate */ 39 | 40 | #include "comp.h" 41 | #include "modem_stats.h" 42 | 43 | struct COHPSK; 44 | 45 | extern const int test_bits_coh[]; 46 | 47 | struct COHPSK *cohpsk_create(void); 48 | void cohpsk_destroy(struct COHPSK *coh); 49 | void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[], int nbits); 50 | void cohpsk_clip(COMP tx_fdm[]); 51 | void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame); 52 | void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats); 53 | void cohpsk_set_verbose(struct COHPSK *coh, int verbose); 54 | void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]); 55 | void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[], 56 | int *bit_errors, char rx_bits[], int channel); 57 | int cohpsk_error_pattern_size(void); 58 | void cohpsk_set_frame(struct COHPSK *coh, int frame); 59 | void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, 60 | COMP *foff_phase_rect, int nin); 61 | 62 | /* used for accessing upper and lower bits before diversity combination */ 63 | 64 | float *cohpsk_get_rx_bits_lower(struct COHPSK *coh); 65 | float *cohpsk_get_rx_bits_upper(struct COHPSK *coh); 66 | void cohpsk_set_carrier_ampl(struct COHPSK *coh, int c, float ampl); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/codec2/codec2_fdmdv.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_fdmdv.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: April 14 2012 6 | 7 | A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice 8 | (FDMDV) modem. Used for digital audio over HF SSB. See 9 | README_fdmdv.txt for more information, and fdmdv_mod.c and 10 | fdmdv_demod.c for example usage. 11 | 12 | The name codec2_fdmdv.h is used to make it unique when "make 13 | installed". 14 | 15 | References: 16 | 17 | [1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf 18 | 19 | \*---------------------------------------------------------------------------*/ 20 | 21 | /* 22 | Copyright (C) 2012 David Rowe 23 | 24 | All rights reserved. 25 | 26 | This program is free software; you can redistribute it and/or modify 27 | it under the terms of the GNU Lesser General Public License version 2.1, as 28 | published by the Free Software Foundation. This program is 29 | distributed in the hope that it will be useful, but WITHOUT ANY 30 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 31 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 32 | License for more details. 33 | 34 | You should have received a copy of the GNU Lesser General Public License 35 | along with this program; if not, see . 36 | */ 37 | 38 | #ifndef __FDMDV__ 39 | #define __FDMDV__ 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* set up the calling convention for DLL function import/export for 46 | WIN32 cross compiling */ 47 | 48 | #ifdef __CODEC2_WIN32__ 49 | #ifdef __CODEC2_BUILDING_DLL__ 50 | #define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall 51 | #else 52 | #define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall 53 | #endif 54 | #else 55 | #define CODEC2_WIN32SUPPORT 56 | #endif 57 | 58 | #include "comp.h" 59 | #include "modem_stats.h" 60 | 61 | #define FDMDV_NC 14 /* default number of data carriers */ 62 | #define FDMDV_NC_MAX 20 /* maximum number of data carriers */ 63 | #define FDMDV_BITS_PER_FRAME 28 /* 20ms frames, for nominal 1400 bit/s */ 64 | #define FDMDV_NOM_SAMPLES_PER_FRAME 160 /* modulator output samples/frame and nominal demod samples/frame */ 65 | /* at 8000 Hz sample rate */ 66 | #define FDMDV_MAX_SAMPLES_PER_FRAME 200 /* max demod samples/frame, use this to allocate storage */ 67 | #define FDMDV_SCALE 1000 /* suggested scaling for 16 bit shorts */ 68 | #define FDMDV_FCENTRE 1500 /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */ 69 | 70 | /* 8 to 48 kHz sample rate conversion */ 71 | 72 | #define FDMDV_OS 2 /* oversampling rate */ 73 | #define FDMDV_OS_TAPS_16K 48 /* number of OS filter taps at 16kHz */ 74 | #define FDMDV_OS_TAPS_8K (FDMDV_OS_TAPS_16K/FDMDV_OS) /* number of OS filter taps at 8kHz */ 75 | 76 | /* FDMDV states and stats structures */ 77 | 78 | struct FDMDV; 79 | 80 | struct FDMDV * fdmdv_create(int Nc); 81 | void fdmdv_destroy(struct FDMDV *fdmdv_state); 82 | void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state); 83 | int fdmdv_bits_per_frame(struct FDMDV *fdmdv_state); 84 | float fdmdv_get_fsep(struct FDMDV *fdmdv_state); 85 | void fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep); 86 | 87 | void fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit); 88 | void fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin); 89 | 90 | void fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]); 91 | int fdmdv_error_pattern_size(struct FDMDV *fdmdv_state); 92 | void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]); 93 | 94 | void fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct MODEM_STATS *stats); 95 | 96 | void fdmdv_8_to_16(float out16k[], float in8k[], int n); 97 | void fdmdv_8_to_16_short(short out16k[], short in8k[], int n); 98 | void fdmdv_16_to_8(float out8k[], float in16k[], int n); 99 | void fdmdv_16_to_8_short(short out8k[], short in16k[], int n); 100 | 101 | void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin); 102 | 103 | /* debug/development function(s) */ 104 | 105 | void fdmdv_dump_osc_mags(struct FDMDV *f); 106 | void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif 113 | 114 | -------------------------------------------------------------------------------- /src/codec2/codec2_fft.c: -------------------------------------------------------------------------------- 1 | /* 2 | * codec2_fft.c 3 | * 4 | * Created on: 24.09.2016 5 | * Author: danilo 6 | */ 7 | 8 | #include "codec2_fft.h" 9 | #ifdef USE_KISS_FFT 10 | #include "_kiss_fft_guts.h" 11 | 12 | #else 13 | #if 0 14 | // caching constants in RAM did not seem to have an effect on performance 15 | // TODO: Decide what to with this code 16 | #define FFT_INIT_CACHE_SIZE 4 17 | const arm_cfft_instance_f32* fft_init_cache[FFT_INIT_CACHE_SIZE]; 18 | 19 | static const arm_cfft_instance_f32* arm_fft_instance2ram(const arm_cfft_instance_f32* in) 20 | { 21 | 22 | arm_cfft_instance_f32* out = malloc(sizeof(arm_cfft_instance_f32)); 23 | 24 | if (out) { 25 | memcpy(out,in,sizeof(arm_cfft_instance_f32)); 26 | out->pBitRevTable = malloc(out->bitRevLength * sizeof(uint16_t)); 27 | out->pTwiddle = malloc(out->fftLen * sizeof(float32_t)); 28 | memcpy((void*)out->pBitRevTable,in->pBitRevTable,out->bitRevLength * sizeof(uint16_t)); 29 | memcpy((void*)out->pTwiddle,in->pTwiddle,out->fftLen * sizeof(float32_t)); 30 | } 31 | return out; 32 | } 33 | 34 | 35 | static const arm_cfft_instance_f32* arm_fft_cache_get(const arm_cfft_instance_f32* romfft) 36 | { 37 | const arm_cfft_instance_f32* retval = NULL; 38 | static int used = 0; 39 | for (int i = 0; fft_init_cache[i] != NULL && i < used; i++) 40 | { 41 | if (romfft->fftLen == fft_init_cache[i]->fftLen) 42 | { 43 | retval = fft_init_cache[i]; 44 | break; 45 | } 46 | } 47 | if (retval == NULL && used < FFT_INIT_CACHE_SIZE) 48 | { 49 | retval = arm_fft_instance2ram(romfft); 50 | fft_init_cache[used++] = retval; 51 | } 52 | if (retval == NULL) 53 | { 54 | retval = romfft; 55 | } 56 | return retval; 57 | } 58 | #endif 59 | #endif 60 | 61 | void codec2_fft_free(codec2_fft_cfg cfg) 62 | { 63 | #ifdef USE_KISS_FFT 64 | KISS_FFT_FREE(cfg); 65 | #else 66 | free(cfg); 67 | #endif 68 | } 69 | 70 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) 71 | { 72 | codec2_fft_cfg retval; 73 | #ifdef USE_KISS_FFT 74 | retval = kiss_fft_alloc(nfft, inverse_fft, mem, lenmem); 75 | #else 76 | retval = malloc(sizeof(codec2_fft_struct)); 77 | retval->inverse = inverse_fft; 78 | switch(nfft) 79 | { 80 | case 128: 81 | retval->instance = &arm_cfft_sR_f32_len128; 82 | break; 83 | case 256: 84 | retval->instance = &arm_cfft_sR_f32_len256; 85 | break; 86 | case 512: 87 | retval->instance = &arm_cfft_sR_f32_len512; 88 | break; 89 | // case 1024: 90 | // retval->instance = &arm_cfft_sR_f32_len1024; 91 | // break; 92 | default: 93 | abort(); 94 | } 95 | // retval->instance = arm_fft_cache_get(retval->instance); 96 | #endif 97 | return retval; 98 | } 99 | 100 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem) 101 | { 102 | codec2_fftr_cfg retval; 103 | #ifdef USE_KISS_FFT 104 | retval = kiss_fftr_alloc(nfft, inverse_fft, mem, lenmem); 105 | #else 106 | retval = malloc(sizeof(codec2_fftr_struct)); 107 | retval->inverse = inverse_fft; 108 | retval->instance = malloc(sizeof(arm_rfft_fast_instance_f32)); 109 | arm_rfft_fast_init_f32(retval->instance,nfft); 110 | // memcpy(&retval->instance->Sint,arm_fft_cache_get(&retval->instance->Sint),sizeof(arm_cfft_instance_f32)); 111 | #endif 112 | return retval; 113 | } 114 | void codec2_fftr_free(codec2_fftr_cfg cfg) 115 | { 116 | #ifdef USE_KISS_FFT 117 | KISS_FFT_FREE(cfg); 118 | #else 119 | free(cfg->instance); 120 | free(cfg); 121 | #endif 122 | } 123 | 124 | // there is a little overhead for inplace kiss_fft but this is 125 | // on the powerful platforms like the Raspberry or even x86 PC based ones 126 | // not noticeable 127 | // the reduced usage of RAM and increased performance on STM32 platforms 128 | // should be worth it. 129 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout) 130 | { 131 | 132 | #ifdef USE_KISS_FFT 133 | kiss_fft_cpx in[512]; 134 | // decide whether to use the local stack based buffer for in 135 | // or to allow kiss_fft to allocate RAM 136 | // second part is just to play safe since first method 137 | // is much faster and uses less RAM 138 | if (cfg->nfft <= 512) 139 | { 140 | memcpy(in,inout,cfg->nfft*sizeof(kiss_fft_cpx)); 141 | kiss_fft(cfg, in, (kiss_fft_cpx*)inout); 142 | } 143 | else 144 | { 145 | kiss_fft(cfg, (kiss_fft_cpx*)inout, (kiss_fft_cpx*)inout); 146 | } 147 | #else 148 | arm_cfft_f32(cfg->instance,(float*)inout,cfg->inverse,1); 149 | if (cfg->inverse) 150 | { 151 | arm_scale_f32(inout,cfg->instance->fftLen,inout,cfg->instance->fftLen*2); 152 | } 153 | 154 | #endif 155 | } 156 | -------------------------------------------------------------------------------- /src/codec2/codec2_fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * codec2_fft.h 3 | * 4 | * Created on: 17.09.2016 5 | * Author: danilo 6 | */ 7 | 8 | #ifndef DRIVERS_FREEDV_CODEC2_FFT_H_ 9 | #define DRIVERS_FREEDV_CODEC2_FFT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef ARM_MATH_CM4 18 | #include "stm32f4xx.h" 19 | #include "core_cm4.h" 20 | #include "arm_math.h" 21 | #include "arm_const_structs.h" 22 | #endif 23 | 24 | #include "defines.h" 25 | #include "comp.h" 26 | 27 | #ifndef ARM_MATH_CM4 28 | #define USE_KISS_FFT 29 | #endif 30 | // #define USE_KISS_FFT 31 | 32 | 33 | typedef COMP codec2_fft_cpx; 34 | #include "kiss_fftr.h" 35 | 36 | #ifdef USE_KISS_FFT 37 | #include "kiss_fft.h" 38 | typedef kiss_fftr_cfg codec2_fftr_cfg; 39 | typedef kiss_fft_cfg codec2_fft_cfg; 40 | typedef kiss_fft_scalar codec2_fft_scalar; 41 | #else 42 | typedef float32_t codec2_fft_scalar; 43 | typedef struct { 44 | arm_rfft_fast_instance_f32* instance; 45 | int inverse; 46 | } codec2_fftr_struct; 47 | 48 | typedef codec2_fftr_struct* codec2_fftr_cfg; 49 | 50 | typedef struct { 51 | const arm_cfft_instance_f32* instance; 52 | int inverse; 53 | } codec2_fft_struct; 54 | typedef codec2_fft_struct* codec2_fft_cfg; 55 | #endif 56 | 57 | 58 | 59 | static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, codec2_fft_cpx* out) 60 | { 61 | 62 | #ifdef USE_KISS_FFT 63 | kiss_fftr(cfg, in, (kiss_fft_cpx*)out); 64 | #else 65 | arm_rfft_fast_f32(cfg->instance,in,(float*)out,cfg->inverse); 66 | out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag 67 | #endif 68 | } 69 | 70 | static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, codec2_fft_scalar* out) 71 | { 72 | #ifdef USE_KISS_FFT 73 | kiss_fftri(cfg, (kiss_fft_cpx*)in, out); 74 | #else 75 | arm_rfft_fast_f32(cfg->instance,(float*)in,out,cfg->inverse); 76 | // arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT); 77 | #endif 78 | 79 | } 80 | 81 | codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); 82 | codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem); 83 | void codec2_fft_free(codec2_fft_cfg cfg); 84 | void codec2_fftr_free(codec2_fftr_cfg cfg); 85 | 86 | 87 | static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out) 88 | { 89 | 90 | #ifdef USE_KISS_FFT 91 | kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out); 92 | #else 93 | memcpy(out,in,cfg->instance->fftLen*2*sizeof(float)); 94 | arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse,0); 95 | // TODO: this is not nice, but for now required to keep changes minimal 96 | // however, since main goal is to reduce the memory usage 97 | // we should convert to an in place interface 98 | // on PC like platforms the overhead of using the "inplace" kiss_fft calls 99 | // is neglectable compared to the gain in memory usage on STM32 platforms 100 | if (cfg->inverse) 101 | { 102 | arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2); 103 | } 104 | #endif 105 | } 106 | 107 | void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout); 108 | 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/codec2/codec2_fifo.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_fifo.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: Oct 15 2012 6 | 7 | A FIFO design useful in gluing the FDMDV modem and codec together in 8 | integrated applications. 9 | 10 | The name codec2_fifo.h is used to make it unique when "make 11 | installed". 12 | 13 | \*---------------------------------------------------------------------------*/ 14 | 15 | /* 16 | Copyright (C) 2012 David Rowe 17 | 18 | All rights reserved. 19 | 20 | This program is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License version 2.1, as 22 | published by the Free Software Foundation. This program is 23 | distributed in the hope that it will be useful, but WITHOUT ANY 24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 26 | License for more details. 27 | 28 | You should have received a copy of the GNU Lesser General Public License 29 | along with this program; if not, see . 30 | */ 31 | 32 | #ifndef __FIFO__ 33 | #define __FIFO__ 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | struct FIFO; 40 | 41 | struct FIFO *fifo_create(int nshort); 42 | void fifo_destroy(struct FIFO *fifo); 43 | int fifo_write(struct FIFO *fifo, short data[], int n); 44 | int fifo_read(struct FIFO *fifo, short data[], int n); 45 | 46 | /*! 47 | * Return the number of bytes stored in the FIFO. 48 | */ 49 | int fifo_used(const struct FIFO * const fifo); 50 | 51 | /*! 52 | * Return the space available in the FIFO. 53 | */ 54 | int fifo_free(const struct FIFO * const fifo); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/codec2/codec2_fm.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_fm.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: February 2015 6 | 7 | Functions that implement analog FM, see also octave/fm.m. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2015 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __CODEC2_FM__ 29 | #define __CODEC2_FM__ 30 | 31 | #include "comp.h" 32 | 33 | struct FM { 34 | float Fs; /* setme: sample rate */ 35 | float fm_max; /* setme: maximum modulation frequency */ 36 | float fd; /* setme: maximum deviation */ 37 | float fc; /* setme: carrier frequency */ 38 | COMP *rx_bb; 39 | COMP rx_bb_filt_prev; 40 | float *rx_dem_mem; 41 | float tx_phase; 42 | int nsam; 43 | COMP lo_phase; 44 | }; 45 | 46 | struct FM *fm_create(int nsam); 47 | void fm_destroy(struct FM *fm_states); 48 | void fm_demod(struct FM *fm, float rx_out[], float rx[]); 49 | void fm_mod(struct FM *fm, float tx_in[], float tx_out[]); 50 | void fm_mod_comp(struct FM *fm_states, float tx_in[], COMP tx_out[]); 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /src/codec2/codec2_internal.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_internal.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: April 16 2012 6 | 7 | Header file for Codec2 internal states, exposed via this header 8 | file to assist in testing. 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright (C) 2012 David Rowe 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | */ 28 | 29 | #ifndef __CODEC2_INTERNAL__ 30 | #define __CODEC2_INTERNAL__ 31 | 32 | #include "codec2_fft.h" 33 | 34 | struct CODEC2 { 35 | int mode; 36 | C2CONST c2const; 37 | int Fs; 38 | int n_samp; 39 | int m_pitch; 40 | codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ 41 | codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ 42 | float *w; /* [m_pitch] time domain hamming window */ 43 | COMP W[FFT_ENC]; /* DFT of w[] */ 44 | float *Pn; /* [2*n_samp] trapezoidal synthesis window */ 45 | float *bpf_buf; /* buffer for band pass filter */ 46 | float *Sn; /* [m_pitch] input speech */ 47 | float hpf_states[2]; /* high pass filter states */ 48 | void *nlp; /* pitch predictor states */ 49 | int gray; /* non-zero for gray encoding */ 50 | 51 | codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ 52 | float *Sn_; /* [2*n_samp] synthesised output speech */ 53 | float ex_phase; /* excitation model phase track */ 54 | float bg_est; /* background noise estimate for post filter */ 55 | float prev_f0_enc; /* previous frame's f0 estimate */ 56 | MODEL prev_model_dec; /* previous frame's model parameters */ 57 | float prev_lsps_dec[LPC_ORD]; /* previous frame's LSPs */ 58 | float prev_e_dec; /* previous frame's LPC energy */ 59 | 60 | int lpc_pf; /* LPC post filter on */ 61 | int bass_boost; /* LPC post filter bass boost */ 62 | float beta; /* LPC post filter parameters */ 63 | float gamma; 64 | 65 | float xq_enc[2]; /* joint pitch and energy VQ states */ 66 | float xq_dec[2]; 67 | 68 | int smoothing; /* enable smoothing for channels with errors */ 69 | float *softdec; /* optional soft decn bits from demod */ 70 | 71 | /* newamp1 states */ 72 | 73 | float Wo_left; 74 | int voicing_left; 75 | codec2_fft_cfg phase_fft_fwd_cfg; 76 | codec2_fft_cfg phase_fft_inv_cfg; 77 | }; 78 | 79 | // test and debug 80 | void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); 81 | void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, 82 | COMP Aw[]); 83 | #endif 84 | -------------------------------------------------------------------------------- /src/codec2/codec2_ofdm.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: codec2_ofdm.h 4 | AUTHORS.....: David Rowe & Steve Sampson 5 | DATE CREATED: June 2017 6 | 7 | External user references to the modem library. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2017 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef CODEC2_OFDM_H 29 | #define CODEC2_OFDM_H 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /* Includes */ 36 | 37 | #include 38 | #include 39 | 40 | #include "comp.h" 41 | 42 | /* Defines */ 43 | 44 | struct OFDM; 45 | 46 | /* Prototypes */ 47 | 48 | struct OFDM *ofdm_create(void); 49 | void ofdm_destroy(struct OFDM *); 50 | void ofdm_mod(struct OFDM *, COMP *, const int *); 51 | void ofdm_demod(struct OFDM *, int *, COMP *); 52 | int ofdm_get_nin(struct OFDM *); 53 | int ofdm_get_samples_per_frame(void); 54 | int ofdm_get_max_samples_per_frame(void); 55 | 56 | /* option setters */ 57 | 58 | void ofdm_set_verbose(struct OFDM *, int); 59 | void ofdm_set_timing_enable(struct OFDM *, bool); 60 | void ofdm_set_foff_est_enable(struct OFDM *, bool); 61 | void ofdm_set_phase_est_enable(struct OFDM *, bool); 62 | void ofdm_set_off_est_hz(struct OFDM *, float); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /src/codec2/cohpsk_defs.h: -------------------------------------------------------------------------------- 1 | /* Generated by write_pilot_file() Octave function */ 2 | 3 | #define NSYMROW 4 /* number of data symbols per carrier (number of rows) */ 4 | #define NS 4 /* number of data symbols between pilots */ 5 | #define NPILOTSFRAME 2 /* number of pilot symbols per carrier */ 6 | #define PILOTS_NC 7 /* number of carriers */ 7 | 8 | #define NSYMROWPILOT 6 /* number of rows after pilots inserted */ 9 | 10 | -------------------------------------------------------------------------------- /src/codec2/cohpsk_internal.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: cohpsk_internal.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: March 2015 6 | 7 | Functions that implement a coherent PSK FDM modem. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2015 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __COHPSK_INTERNAL__ 29 | #define __COHPSK_INTERNAL__ 30 | 31 | #define NCT_SYMB_BUF (2*NSYMROWPILOT+2) 32 | #define ND 2 /* diversity factor ND 1 is no diveristy, ND we have orginal plus 33 | one copy */ 34 | #define NSW 4 /* number of sync window frames */ 35 | #define COHPSK_ND 2 /* diversity factor */ 36 | #define COHPSK_M 100 /* oversampling rate */ 37 | #define COHPSK_NSYM 6 38 | #define COHPSK_NFILTER (COHPSK_NSYM*COHPSK_M) 39 | #define COHPSK_EXCESS_BW 0.5 /* excess BW factor of root nyq filter */ 40 | #define COHPSK_NT 5 /* number of symbols we estimate timing over */ 41 | #define COHPSK_CLIP 6.5 /* hard clipping for Nc*Nc=14 to reduce PAPR */ 42 | 43 | #include "fdmdv_internal.h" 44 | #include "kiss_fft.h" 45 | 46 | struct COHPSK { 47 | COMP ch_fdm_frame_buf[NSW*NSYMROWPILOT*COHPSK_M]; /* buffer of several frames of symbols from channel */ 48 | float pilot2[2*NPILOTSFRAME][COHPSK_NC]; 49 | float phi_[NSYMROWPILOT][COHPSK_NC*ND]; /* phase estimates for this frame of rx data symbols */ 50 | float amp_[NSYMROW][COHPSK_NC*ND]; /* amplitude estimates for this frame of rx data symbols */ 51 | COMP rx_symb[NSYMROWPILOT][COHPSK_NC*ND]; /* demodulated symbols */ 52 | float f_est; 53 | COMP rx_filter_memory[COHPSK_NC*ND][COHPSK_NFILTER]; 54 | COMP ct_symb_buf[NCT_SYMB_BUF][COHPSK_NC*ND]; 55 | int ct; /* coarse timing offset in symbols */ 56 | float rx_timing; /* fine timing for last symbol in frame */ 57 | int nin; /* number of samples to input for next symbol */ 58 | float f_fine_est; 59 | COMP ff_rect; 60 | COMP ff_phase; 61 | COMP ct_symb_ff_buf[NSYMROWPILOT+2][COHPSK_NC*ND]; 62 | int sync; 63 | int sync_timer; 64 | 65 | int frame; 66 | float ratio; 67 | 68 | float sig_rms; 69 | float noise_rms; 70 | 71 | struct FDMDV *fdmdv; 72 | 73 | int verbose; 74 | 75 | int *ptest_bits_coh_tx; 76 | int *ptest_bits_coh_rx[2]; 77 | int *ptest_bits_coh_end; 78 | 79 | /* counting bit errors using pilots */ 80 | 81 | int npilotbits; 82 | int npilotbiterrors; 83 | 84 | /* optional log variables used for testing Octave to C port */ 85 | 86 | COMP *rx_baseband_log; 87 | int rx_baseband_log_col_index; 88 | int rx_baseband_log_col_sz; 89 | 90 | COMP *rx_filt_log; 91 | int rx_filt_log_col_index; 92 | int rx_filt_log_col_sz; 93 | 94 | COMP *ch_symb_log; 95 | int ch_symb_log_r; 96 | int ch_symb_log_col_sz; 97 | 98 | float *rx_timing_log; 99 | int rx_timing_log_index; 100 | 101 | /* demodulated bits before diversity combination for test/instrumentation purposes */ 102 | 103 | float rx_bits_lower[COHPSK_BITS_PER_FRAME]; 104 | float rx_bits_upper[COHPSK_BITS_PER_FRAME]; 105 | 106 | /* tx amplitude weights for each carrier for test/instrumentation */ 107 | 108 | float carrier_ampl[COHPSK_NC*ND]; 109 | }; 110 | 111 | void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC*COHPSK_ND], int tx_bits[], int nbits); 112 | void qpsk_symbols_to_bits(struct COHPSK *coh, float rx_bits[], COMP ct_symb_buf[][COHPSK_NC*COHPSK_ND]); 113 | void tx_filter_and_upconvert_coh(COMP tx_fdm[], int Nc, COMP tx_symbols[], 114 | COMP tx_filter_memory[COHPSK_NC][COHPSK_NSYM], 115 | COMP phase_tx[], COMP freq[], 116 | COMP *fbb_phase, COMP fbb_rect); 117 | void fdm_downconvert_coh(COMP rx_baseband[COHPSK_NC][COHPSK_M+COHPSK_M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin); 118 | void rx_filter_coh(COMP rx_filt[COHPSK_NC+1][P+1], int Nc, COMP rx_baseband[COHPSK_NC+1][COHPSK_M+COHPSK_M/P], COMP rx_filter_memory[COHPSK_NC+1][COHPSK_NFILTER], int nin); 119 | void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*COHPSK_ND], int sync, int *next_sync); 120 | void fine_freq_correct(struct COHPSK *coh, int sync, int next_sync); 121 | int sync_state_machine(struct COHPSK *coh, int sync, int next_sync); 122 | int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm); 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/codec2/comp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: comp.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 24/08/09 6 | 7 | Complex number definition. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __COMP__ 29 | #define __COMP__ 30 | 31 | /* Complex number */ 32 | 33 | typedef struct { 34 | float real; 35 | float imag; 36 | } COMP; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/codec2/comp_prim.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: comp_prim.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: Marh 2015 6 | 7 | Complex number maths primitives. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2015 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __COMP_PRIM__ 29 | #define __COMP_PRIM__ 30 | 31 | /*---------------------------------------------------------------------------*\ 32 | 33 | FUNCTIONS 34 | 35 | \*---------------------------------------------------------------------------*/ 36 | 37 | inline static COMP cneg(COMP a) 38 | { 39 | COMP res; 40 | 41 | res.real = -a.real; 42 | res.imag = -a.imag; 43 | 44 | return res; 45 | } 46 | 47 | inline static COMP cconj(COMP a) 48 | { 49 | COMP res; 50 | 51 | res.real = a.real; 52 | res.imag = -a.imag; 53 | 54 | return res; 55 | } 56 | 57 | inline static COMP cmult(COMP a, COMP b) 58 | { 59 | COMP res; 60 | 61 | res.real = a.real*b.real - a.imag*b.imag; 62 | res.imag = a.real*b.imag + a.imag*b.real; 63 | 64 | return res; 65 | } 66 | 67 | inline static COMP fcmult(float a, COMP b) 68 | { 69 | COMP res; 70 | 71 | res.real = a*b.real; 72 | res.imag = a*b.imag; 73 | 74 | return res; 75 | } 76 | 77 | inline static COMP cadd(COMP a, COMP b) 78 | { 79 | COMP res; 80 | 81 | res.real = a.real + b.real; 82 | res.imag = a.imag + b.imag; 83 | 84 | return res; 85 | } 86 | 87 | inline static float cabsolute(COMP a) 88 | { 89 | return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0)); 90 | } 91 | 92 | /* 93 | * Euler's formula in a new convenient function 94 | */ 95 | inline static COMP comp_exp_j(float phi){ 96 | COMP res; 97 | res.real = cosf(phi); 98 | res.imag = sinf(phi); 99 | return res; 100 | } 101 | 102 | /* 103 | * Quick and easy complex 0 104 | */ 105 | inline static COMP comp0(){ 106 | COMP res; 107 | res.real = 0; 108 | res.imag = 0; 109 | return res; 110 | } 111 | 112 | /* 113 | * Quick and easy complex subtract 114 | */ 115 | inline static COMP csub(COMP a, COMP b){ 116 | COMP res; 117 | res.real = a.real-b.real; 118 | res.imag = a.imag-b.imag; 119 | return res; 120 | } 121 | 122 | /* 123 | * Compare the magnitude of a and b. if |a|>|b|, return true, otw false. 124 | * This needs no square roots 125 | */ 126 | inline static int comp_mag_gt(COMP a,COMP b){ 127 | return ((a.real*a.real)+(a.imag*a.imag)) > ((b.real*b.real)+(b.imag*b.imag)); 128 | } 129 | 130 | /* 131 | * Normalize a complex number's magnitude to 1 132 | */ 133 | inline static COMP comp_normalize(COMP a){ 134 | COMP b; 135 | float av = cabsolute(a); 136 | b.real = a.real/av; 137 | b.imag = a.imag/av; 138 | return b; 139 | } 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /src/codec2/defines.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: defines.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 23/4/93 6 | 7 | Defines and structures used throughout the codec. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __DEFINES__ 29 | #define __DEFINES__ 30 | 31 | /*---------------------------------------------------------------------------*\ 32 | 33 | DEFINES 34 | 35 | \*---------------------------------------------------------------------------*/ 36 | 37 | /* General defines */ 38 | 39 | #define N_S 0.010 /* buffer size in s */ 40 | #define TW_S 0.005 /* trapezoidal synth window overlap */ 41 | #define MAX_AMP 160 /* maximum number of harmonics */ 42 | #ifndef PI 43 | #define PI 3.141592654 /* mathematical constant */ 44 | #endif 45 | #define TWO_PI 6.283185307 /* mathematical constant */ 46 | #define MAX_STR 2048 /* maximum string size */ 47 | 48 | #define FFT_ENC 512 /* size of FFT used for encoder */ 49 | #define FFT_DEC 512 /* size of FFT used in decoder */ 50 | #define V_THRESH 6.0 /* voicing threshold in dB */ 51 | #define LPC_ORD 10 /* LPC order */ 52 | #define LPC_ORD_LOW 6 /* LPC order for lower rates */ 53 | 54 | /* Pitch estimation defines */ 55 | 56 | #define M_PITCH_S 0.0400 /* pitch analysis window in s */ 57 | #define P_MIN_S 0.0025 /* minimum pitch period in s */ 58 | #define P_MAX_S 0.0200 /* maximum pitch period in s */ 59 | 60 | /*---------------------------------------------------------------------------*\ 61 | 62 | TYPEDEFS 63 | 64 | \*---------------------------------------------------------------------------*/ 65 | 66 | /* Structure to hold constants calculated at run time based on sample rate */ 67 | 68 | typedef struct { 69 | int Fs; /* sample rate of this instance */ 70 | int n_samp; /* number of samples per 10ms frame at Fs */ 71 | int max_amp; /* maximum number of harmonics */ 72 | int m_pitch; /* pitch estimation window size in samples */ 73 | int p_min; /* minimum pitch period in samples */ 74 | int p_max; /* maximum pitch period in samples */ 75 | float Wo_min; 76 | float Wo_max; 77 | int nw; /* analysis window size in samples */ 78 | int tw; /* trapezoidal synthesis window overlap */ 79 | } C2CONST; 80 | 81 | /* Structure to hold model parameters for one frame */ 82 | 83 | typedef struct { 84 | float Wo; /* fundamental frequency estimate in radians */ 85 | int L; /* number of harmonics */ 86 | float A[MAX_AMP+1]; /* amplitiude of each harmonic */ 87 | float phi[MAX_AMP+1]; /* phase of each harmonic */ 88 | int voiced; /* non-zero if this frame is voiced */ 89 | } MODEL; 90 | 91 | /* describes each codebook */ 92 | 93 | struct lsp_codebook { 94 | int k; /* dimension of vector */ 95 | int log2m; /* number of bits in m */ 96 | int m; /* elements in codebook */ 97 | const float * cb; /* The elements */ 98 | }; 99 | 100 | extern const struct lsp_codebook lsp_cb[]; 101 | extern const struct lsp_codebook lsp_cbd[]; 102 | extern const struct lsp_codebook lsp_cbvq[]; 103 | extern const struct lsp_codebook lsp_cbjnd[]; 104 | extern const struct lsp_codebook lsp_cbdt[]; 105 | extern const struct lsp_codebook lsp_cbjvm[]; 106 | extern const struct lsp_codebook lsp_cbvqanssi[]; 107 | extern const struct lsp_codebook mel_cb[]; 108 | extern const struct lsp_codebook ge_cb[]; 109 | extern const struct lsp_codebook lspmelvq_cb[]; 110 | extern const struct lsp_codebook newamp1vq_cb[]; 111 | extern const struct lsp_codebook newamp1_energy_cb[]; 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /src/codec2/dump.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: dump.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 25/8/09 6 | 7 | Routines to dump data to text files for Octave analysis. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | All rights reserved. 13 | 14 | This program is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License version 2.1, as 16 | published by the Free Software Foundation. This program is 17 | distributed in the hope that it will be useful, but WITHOUT ANY 18 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 20 | License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with this program; if not, see . 24 | */ 25 | 26 | #ifndef __DUMP__ 27 | #define __DUMP__ 28 | 29 | #include "defines.h" 30 | #include "comp.h" 31 | #include "codec2_fft.h" 32 | #include "codec2_internal.h" 33 | 34 | void dump_on(char filename_prefix[]); 35 | void dump_off(); 36 | 37 | void dump_Sn(int m_pitch, float Sn[]); 38 | void dump_Sw(COMP Sw[]); 39 | void dump_Sw_(COMP Sw_[]); 40 | void dump_Ew(COMP Ew[]); 41 | void dump_softdec(float *softdec, int n); 42 | 43 | /* amplitude modelling */ 44 | 45 | void dump_model(MODEL *m); 46 | void dump_quantised_model(MODEL *m); 47 | void dump_Pwn(COMP Pw[]); 48 | void dump_Pw(float Pw[]); 49 | void dump_Rw(float Rw[]); 50 | void dump_lsp(float lsp[]); 51 | void dump_weights(float w[], int ndim); 52 | void dump_lsp_(float lsp_[]); 53 | void dump_mel(float mel[], int order); 54 | void dump_mel_indexes(int mel_indexes[], int order); 55 | void dump_ak(float ak[], int order); 56 | void dump_ak_(float ak[], int order); 57 | void dump_E(float E); 58 | void dump_lpc_snr(float snr); 59 | 60 | /* phase modelling */ 61 | 62 | void dump_snr(float snr); 63 | void dump_phase(float phase[], int L); 64 | void dump_phase_(float phase[], int L); 65 | void dump_hephase(int ind[], int dim); 66 | 67 | /* NLP states */ 68 | 69 | void dump_sq(int m_pitch, float sq[]); 70 | void dump_dec(COMP Fw[]); 71 | void dump_Fw(COMP Fw[]); 72 | void dump_e(float e_hz[]); 73 | #if 0 74 | void dump_Rk(float Rk[]); 75 | #endif 76 | 77 | /* post filter */ 78 | 79 | void dump_bg(float e, float bg_est, float percent_uv); 80 | void dump_Pwb(float Pwb[]); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/codec2/fifo.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: fifo.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: Oct 15 2012 6 | 7 | A FIFO design useful in gluing the FDMDV modem and codec together in 8 | integrated applications. The unittest/tfifo indicates these 9 | routines are thread safe without the need for syncronisation 10 | object, e.g. a different thread can read and write to a fifo at the 11 | same time. 12 | 13 | \*---------------------------------------------------------------------------*/ 14 | 15 | /* 16 | Copyright (C) 2012 David Rowe 17 | 18 | All rights reserved. 19 | 20 | This program is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License version 2.1, as 22 | published by the Free Software Foundation. This program is 23 | distributed in the hope that it will be useful, but WITHOUT ANY 24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 26 | License for more details. 27 | 28 | You should have received a copy of the GNU Lesser General Public License 29 | along with this program; if not, see . 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "codec2_fifo.h" 36 | 37 | struct FIFO { 38 | short *buf; 39 | short *pin; 40 | short *pout; 41 | int nshort; 42 | }; 43 | 44 | struct FIFO *fifo_create(int nshort) { 45 | struct FIFO *fifo; 46 | 47 | fifo = (struct FIFO *)malloc(sizeof(struct FIFO)); 48 | assert(fifo != NULL); 49 | 50 | fifo->buf = (short*)malloc(sizeof(short)*nshort); 51 | assert(fifo->buf != NULL); 52 | fifo->pin = fifo->buf; 53 | fifo->pout = fifo->buf; 54 | fifo->nshort = nshort; 55 | 56 | return fifo; 57 | } 58 | 59 | void fifo_destroy(struct FIFO *fifo) { 60 | assert(fifo != NULL); 61 | free(fifo->buf); 62 | free(fifo); 63 | } 64 | 65 | int fifo_write(struct FIFO *fifo, short data[], int n) { 66 | int i; 67 | short *pdata; 68 | short *pin = fifo->pin; 69 | 70 | assert(fifo != NULL); 71 | assert(data != NULL); 72 | 73 | if (n > fifo_free(fifo)) { 74 | return -1; 75 | } 76 | else { 77 | 78 | /* This could be made more efficient with block copies 79 | using memcpy */ 80 | 81 | pdata = data; 82 | for(i=0; ibuf + fifo->nshort)) 85 | pin = fifo->buf; 86 | } 87 | fifo->pin = pin; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | int fifo_read(struct FIFO *fifo, short data[], int n) 94 | { 95 | int i; 96 | short *pdata; 97 | short *pout = fifo->pout; 98 | 99 | assert(fifo != NULL); 100 | assert(data != NULL); 101 | 102 | if (n > fifo_used(fifo)) { 103 | return -1; 104 | } 105 | else { 106 | 107 | /* This could be made more efficient with block copies 108 | using memcpy */ 109 | 110 | pdata = data; 111 | for(i=0; ibuf + fifo->nshort)) 114 | pout = fifo->buf; 115 | } 116 | fifo->pout = pout; 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | int fifo_used(const struct FIFO * const fifo) 123 | { 124 | short *pin = fifo->pin; 125 | short *pout = fifo->pout; 126 | unsigned int used; 127 | 128 | assert(fifo != NULL); 129 | if (pin >= pout) 130 | used = pin - pout; 131 | else 132 | used = fifo->nshort + (unsigned int)(pin - pout); 133 | 134 | return used; 135 | } 136 | 137 | int fifo_free(const struct FIFO * const fifo) 138 | { 139 | // available storage is one less than nshort as prd == pwr 140 | // is reserved for empty rather than full 141 | 142 | return fifo->nshort - fifo_used(fifo) - 1; 143 | } 144 | -------------------------------------------------------------------------------- /src/codec2/fmfsk.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: fmfsk.h 4 | AUTHOR......: Brady O'Brien 5 | DATE CREATED: 6 February 2016 6 | 7 | C Implementation of 2FSK+Manchester over FM modulator/demodulator, based 8 | on mancyfsk.m and fmfsk.m 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright (C) 2016 David Rowe 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | */ 28 | 29 | #ifndef __C2FMFSK_H 30 | #define __C2FMFSK_H 31 | #include 32 | #include "comp.h" 33 | #include "modem_stats.h" 34 | 35 | #define FMFSK_SCALE 16383 36 | 37 | /* 38 | * fm-me-2fsk state 39 | */ 40 | struct FMFSK{ 41 | /* Static fmfsk parameters */ 42 | int Rb; /* Manchester-encoded bitrate */ 43 | int Rs; /* Raw modem symbol rate */ 44 | int Fs; /* Sample rate */ 45 | int Ts; /* Samples-per-symbol */ 46 | int N; /* Sample processing buffer size */ 47 | int nsym; /* Number of raw modem symbols processed per demod call */ 48 | int nbit; /* Number of bits spit out per demod call */ 49 | int nmem; /* Number of samples kept around between demod calls */ 50 | 51 | /* State kept by demod */ 52 | int nin; /* Number of samples to be demod-ed the next cycle */ 53 | int lodd; /* Last integrated sample for odd bitstream generation */ 54 | float * oldsamps; /* Memory of old samples to make clock-offset-tolerance possible */ 55 | 56 | /* Stats generated by demod */ 57 | float norm_rx_timing; /* RX Timing, used to calculate clock offset */ 58 | int ppm; /* Clock offset in parts-per-million */ 59 | float snr_mean; 60 | 61 | /* Modem stat structure */ 62 | struct MODEM_STATS * stats; 63 | }; 64 | 65 | /* 66 | * Create a new fmfsk modem instance. 67 | * 68 | * int Fs - sample rate 69 | * int Rb - non-manchester bitrate 70 | * returns - new struct FMFSK on sucess, NULL on failure 71 | */ 72 | struct FMFSK * fmfsk_create(int Fs,int Rb); 73 | 74 | /* 75 | * Destroys an fmfsk modem and deallocates memory 76 | */ 77 | void fmfsk_destroy(struct FMFSK *fmfsk); 78 | 79 | /* 80 | * Deposit demod statistics into a MODEM_STATS struct 81 | */ 82 | void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats); 83 | 84 | /* 85 | * Returns the number of samples that must be fed to fmfsk_demod the next 86 | * cycle 87 | */ 88 | uint32_t fmfsk_nin(struct FMFSK *fmfsk); 89 | 90 | /* 91 | * Modulates nbit bits into N samples to be sent through an FM radio 92 | * 93 | * struct FSK *fsk - FSK config/state struct, set up by fsk_create 94 | * float mod_out[] - Buffer for N samples of modulated FMFSK 95 | * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits 96 | */ 97 | void fmfsk_mod(struct FMFSK *fmfsk, float fmfsk_out[],uint8_t bits_in[]); 98 | 99 | 100 | /* 101 | * Demodulate some number of FMFSK samples. The number of samples to be 102 | * demodulated can be found by calling fmfsk_nin(). 103 | * 104 | * struct FMFSK *fsk - FMFSK config/state struct, set up by fsk_create 105 | * uint8_t rx_bits[] - Buffer for nbit unpacked bits to be written 106 | * float fsk_in[] - nin samples of modualted FMFSK from an FM radio 107 | */ 108 | void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]); 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/codec2/freedv_data_channel.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: freedv_data_channel.h 4 | AUTHOR......: Jeroen Vreeken 5 | DATE CREATED: 03 March 2016 6 | 7 | Data channel for ethernet like packets in freedv VHF frames. 8 | Currently designed for- 9 | * 2 control bits per frame 10 | * 4 byte counter bits per frame 11 | * 64 bits of data per frame 12 | \*---------------------------------------------------------------------------*/ 13 | 14 | /* 15 | Copyright (C) 2016 Jeroen Vreeken 16 | 17 | All rights reserved. 18 | 19 | This program is free software; you can redistribute it and/or modify 20 | it under the terms of the GNU Lesser General Public License version 2.1, as 21 | published by the Free Software Foundation. This program is 22 | distributed in the hope that it will be useful, but WITHOUT ANY 23 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 24 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 25 | License for more details. 26 | 27 | You should have received a copy of the GNU Lesser General Public License 28 | along with this program; if not, see . 29 | */ 30 | 31 | #ifndef _FREEDV_DATA_CHANNEL_H 32 | #define _FREEDV_DATA_CHANNEL_H 33 | 34 | #include 35 | 36 | #define FREEDV_DATA_CHANNEL_PACKET_MAX 2048 37 | 38 | typedef void (*freedv_data_callback_rx)(void *, unsigned char *packet, size_t size); 39 | typedef void (*freedv_data_callback_tx)(void *, unsigned char *packet, size_t *size); 40 | 41 | struct freedv_data_channel { 42 | freedv_data_callback_rx cb_rx; 43 | void *cb_rx_state; 44 | freedv_data_callback_tx cb_tx; 45 | void *cb_tx_state; 46 | 47 | unsigned char rx_header[8]; 48 | unsigned char packet_rx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2]; 49 | int packet_rx_cnt; 50 | 51 | unsigned char tx_header[8]; 52 | unsigned char packet_tx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2]; 53 | int packet_tx_cnt; 54 | size_t packet_tx_size; 55 | }; 56 | 57 | 58 | struct freedv_data_channel *freedv_data_channel_create(void); 59 | void freedv_data_channel_destroy(struct freedv_data_channel *fdc); 60 | 61 | void freedv_data_set_cb_rx(struct freedv_data_channel *fdc, freedv_data_callback_rx cb, void *state); 62 | void freedv_data_set_cb_tx(struct freedv_data_channel *fdc, freedv_data_callback_tx cb, void *state); 63 | 64 | void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits); 65 | void freedv_data_channel_tx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int *from_bit, int *bcast_bit, int *crc_bit, int *end_bits); 66 | 67 | void freedv_data_set_header(struct freedv_data_channel *fdc, unsigned char *header); 68 | int freedv_data_get_n_tx_frames(struct freedv_data_channel *fdc, size_t size); 69 | 70 | #endif /* _FREEDV_DATA_CHANNEL_H */ 71 | -------------------------------------------------------------------------------- /src/codec2/freedv_vhf_framing.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: freedv_vhf_framing.h 4 | AUTHOR......: Brady O'Brien 5 | DATE CREATED: 11 February 2016 6 | 7 | Framer and deframer for VHF FreeDV modes 'A' and 'B' 8 | Currently designed for- 9 | * 40ms ota modem frames 10 | * 40ms Codec2 1300 frames 11 | * 52 bits of Codec2 per frame 12 | * 16 bits of unique word per frame 13 | * 28 'spare' bits per frame 14 | * - 4 spare bits at front and end of frame (8 total) for padding 15 | * - 20 'protocol' bits, either for higher layers of 'protocol' or 16 | * - 18 'protocol' bits and 2 vericode sidechannel bits 17 | \*---------------------------------------------------------------------------*/ 18 | 19 | /* 20 | Copyright (C) 2016 David Rowe 21 | 22 | All rights reserved. 23 | 24 | This program is free software; you can redistribute it and/or modify 25 | it under the terms of the GNU Lesser General Public License version 2.1, as 26 | published by the Free Software Foundation. This program is 27 | distributed in the hope that it will be useful, but WITHOUT ANY 28 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 29 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 30 | License for more details. 31 | 32 | You should have received a copy of the GNU Lesser General Public License 33 | along with this program; if not, see . 34 | */ 35 | 36 | #ifndef _FREEDV_VHF_FRAMING_H 37 | #define _FREEDV_VHF_FRAMING_H 38 | 39 | #include "freedv_data_channel.h" 40 | 41 | /* Standard frame type */ 42 | #define FREEDV_VHF_FRAME_A 1 /* 2400A/B Frame */ 43 | #define FREEDV_HF_FRAME_B 2 /* 800XA Frame */ 44 | #define FREEDV_VHF_FRAME_AT 3 /* 4800T Frame */ 45 | 46 | struct freedv_vhf_deframer { 47 | int ftype; /* Type of frame to be looking for */ 48 | int state; /* State of deframer */ 49 | uint8_t * bits; /* Bits currently being decanted */ 50 | uint8_t * invbits; /* Inversion of bits currently being decanted, for FMFSK */ 51 | 52 | int bitptr; /* Pointer into circular bit buffer */ 53 | int miss_cnt; /* How many UWs have been missed */ 54 | int last_uw; /* How many bits since the last UW? */ 55 | int frame_size; /* How big is a frame? */ 56 | int uw_size; /* How big is the UW */ 57 | int on_inv_bits; /* Are we using the inverted bits? */ 58 | int sym_size; /* How many bits in a modem symbol */ 59 | 60 | float ber_est; /* Bit error rate estimate */ 61 | int total_uw_bits; /* Total RX-ed bits of UW */ 62 | int total_uw_err; /* Total errors in UW bits */ 63 | 64 | struct freedv_data_channel *fdc; 65 | }; 66 | 67 | /* Init and allocate memory for a freedv-vhf framer/deframer */ 68 | struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type,int enable_bit_flip); 69 | 70 | /* Get size of various frame parameters */ 71 | /* Frame size in bits */ 72 | int fvhff_get_frame_size(struct freedv_vhf_deframer * def); 73 | /* Codec2 size in bytes */ 74 | int fvhff_get_codec2_size(struct freedv_vhf_deframer * def); 75 | /* Protocol bits in bits */ 76 | int fvhff_get_proto_size(struct freedv_vhf_deframer * def); 77 | /* Varicode bits in bits */ 78 | int fvhff_get_varicode_size(struct freedv_vhf_deframer * def); 79 | 80 | /* Free the memory used by a freedv-vhf framer/deframer */ 81 | void fvhff_destroy_deframer(struct freedv_vhf_deframer * def); 82 | 83 | /* Place codec and other bits into a frame */ 84 | void fvhff_frame_bits(int frame_type,uint8_t bits_out[],uint8_t codec2_in[],uint8_t proto_in[],uint8_t vc_in[]); 85 | void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]); 86 | 87 | /* Find and extract frames from a stream of bits */ 88 | int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]); 89 | 90 | /* Is the de-framer synchronized? */ 91 | int fvhff_synchronized(struct freedv_vhf_deframer * def); 92 | 93 | #endif //_FREEDV_VHF_FRAMING_H 94 | -------------------------------------------------------------------------------- /src/codec2/golay23.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: golay23.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 3 March 2013 6 | 7 | Header file for Golay FEC. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2013 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __GOLAY23__ 29 | #define __GOLAY23__ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | void golay23_init(void); 36 | int golay23_encode(int data); 37 | int golay23_decode(int received_codeword); 38 | int golay23_count_errors(int recd_codeword, int corrected_codeword); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/codec2/horus_l2.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: horus_l2.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: Dec 2015 6 | 7 | \*---------------------------------------------------------------------------*/ 8 | 9 | #ifndef __HORUS_L2__ 10 | #define __HORUS_L2__ 11 | 12 | int horus_l2_get_num_tx_data_bytes(int num_payload_data_bytes); 13 | 14 | /* returns number of output bytes in output_tx_data */ 15 | int horus_l2_encode_tx_packet(unsigned char *output_tx_data, 16 | unsigned char *input_payload_data, 17 | int num_payload_data_bytes); 18 | 19 | void horus_l2_decode_rx_packet(unsigned char *output_payload_data, 20 | unsigned char *input_rx_data, 21 | int num_payload_data_bytes); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/codec2/ht_coeff.h: -------------------------------------------------------------------------------- 1 | /* Hilbert Transform FIR filter coeffs */ 2 | /* Generated by make_hilb Octave script */ 3 | 4 | #define HT_N 100 5 | 6 | COMP ht_coeff[]={ 7 | {0.000000,0.000000}, 8 | {-0.000000,-0.000001}, 9 | {0.000000,0.000000}, 10 | {-0.000000,-0.000017}, 11 | {0.000000,0.000000}, 12 | {0.000000,-0.000079}, 13 | {0.000000,0.000000}, 14 | {0.000000,-0.000217}, 15 | {0.000000,0.000000}, 16 | {0.000000,-0.000461}, 17 | {0.000000,0.000000}, 18 | {-0.000000,-0.000842}, 19 | {0.000000,0.000000}, 20 | {-0.000000,-0.001391}, 21 | {0.000000,0.000000}, 22 | {-0.000000,-0.002140}, 23 | {0.000000,0.000000}, 24 | {-0.000000,-0.003121}, 25 | {0.000000,0.000000}, 26 | {0.000000,-0.004371}, 27 | {0.000000,0.000000}, 28 | {0.000000,-0.005928}, 29 | {0.000000,0.000000}, 30 | {-0.000000,-0.007839}, 31 | {0.000000,0.000000}, 32 | {-0.000000,-0.010159}, 33 | {0.000000,0.000000}, 34 | {-0.000000,-0.012957}, 35 | {0.000000,0.000000}, 36 | {-0.000000,-0.016327}, 37 | {0.000000,0.000000}, 38 | {0.000000,-0.020399}, 39 | {0.000000,0.000000}, 40 | {-0.000000,-0.025364}, 41 | {0.000000,0.000000}, 42 | {0.000000,-0.031512}, 43 | {0.000000,0.000000}, 44 | {0.000000,-0.039319}, 45 | {0.000000,0.000000}, 46 | {0.000000,-0.049610}, 47 | {0.000000,0.000000}, 48 | {-0.000000,-0.063952}, 49 | {0.000000,0.000000}, 50 | {-0.000000,-0.085722}, 51 | {0.000000,0.000000}, 52 | {0.000000,-0.123718}, 53 | {0.000000,0.000000}, 54 | {0.000000,-0.210249}, 55 | {0.000000,0.000000}, 56 | {-0.000000,-0.636250}, 57 | {0.999748,0.000000}, 58 | {0.000000,0.634969}, 59 | {0.000000,0.000000}, 60 | {0.000000,0.208979}, 61 | {0.000000,0.000000}, 62 | {0.000000,0.122467}, 63 | {0.000000,0.000000}, 64 | {-0.000000,0.084502}, 65 | {0.000000,0.000000}, 66 | {0.000000,0.062771}, 67 | {0.000000,0.000000}, 68 | {0.000000,0.048477}, 69 | {0.000000,0.000000}, 70 | {0.000000,0.038242}, 71 | {0.000000,0.000000}, 72 | {-0.000000,0.030497}, 73 | {0.000000,0.000000}, 74 | {0.000000,0.024418}, 75 | {0.000000,0.000000}, 76 | {0.000000,0.019527}, 77 | {0.000000,0.000000}, 78 | {-0.000000,0.015532}, 79 | {0.000000,0.000000}, 80 | {0.000000,0.012242}, 81 | {0.000000,0.000000}, 82 | {-0.000000,0.009524}, 83 | {0.000000,0.000000}, 84 | {-0.000000,0.007285}, 85 | {0.000000,0.000000}, 86 | {-0.000000,0.005454}, 87 | {0.000000,0.000000}, 88 | {-0.000000,0.003973}, 89 | {0.000000,0.000000}, 90 | {0.000000,0.002796}, 91 | {0.000000,0.000000}, 92 | {-0.000000,0.001882}, 93 | {0.000000,0.000000}, 94 | {-0.000000,0.001196}, 95 | {0.000000,0.000000}, 96 | {-0.000000,0.000701}, 97 | {0.000000,0.000000}, 98 | {0.000000,0.000367}, 99 | {0.000000,0.000000}, 100 | {0.000000,0.000160}, 101 | {0.000000,0.000000}, 102 | {0.000000,0.000051}, 103 | {0.000000,0.000000}, 104 | {-0.000000,0.000008}, 105 | {0.000000,0.000000}, 106 | {0.000000,0.000000} 107 | }; -------------------------------------------------------------------------------- /src/codec2/interp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: interp.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 9/10/09 6 | 7 | Interpolation of 20ms frames to 10ms frames. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __INTERP__ 29 | #define __INTERP__ 30 | 31 | #include "kiss_fft.h" 32 | 33 | void interpolate(MODEL *interp, MODEL *prev, MODEL *next); 34 | void interpolate_lsp(kiss_fft_cfg fft_dec_cfg, 35 | MODEL *interp, MODEL *prev, MODEL *next, 36 | float *prev_lsps, float prev_e, 37 | float *next_lsps, float next_e, 38 | float *ak_interp, float *lsps_interp, float Wo_min); 39 | void interp_Wo(MODEL *interp, MODEL *prev, MODEL *next, float Wo_min); 40 | void interp_Wo2(MODEL *interp, MODEL *prev, MODEL *next, float weight, float Wo_min); 41 | float interp_energy(float prev, float next); 42 | float interp_energy2(float prev, float next, float weight); 43 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight, int order); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/codec2/kiss_fft.h: -------------------------------------------------------------------------------- 1 | #ifndef KISS_FFT_H 2 | #define KISS_FFT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /* 14 | ATTENTION! 15 | If you would like a : 16 | -- a utility that will handle the caching of fft objects 17 | -- real-only (no imaginary time component ) FFT 18 | -- a multi-dimensional FFT 19 | -- a command-line utility to perform ffts 20 | -- a command-line utility to perform fast-convolution filtering 21 | 22 | Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c 23 | in the tools/ directory. 24 | */ 25 | 26 | #ifdef USE_SIMD 27 | # include 28 | # define kiss_fft_scalar __m128 29 | #define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) 30 | #define KISS_FFT_FREE _mm_free 31 | #else 32 | #define KISS_FFT_MALLOC malloc 33 | #define KISS_FFT_FREE free 34 | #endif 35 | 36 | 37 | #ifdef FIXED_POINT 38 | #include 39 | # if (FIXED_POINT == 32) 40 | # define kiss_fft_scalar int32_t 41 | # else 42 | # define kiss_fft_scalar int16_t 43 | # endif 44 | #else 45 | # ifndef kiss_fft_scalar 46 | /* default is float */ 47 | # define kiss_fft_scalar float 48 | # endif 49 | #endif 50 | 51 | typedef struct { 52 | kiss_fft_scalar r; 53 | kiss_fft_scalar i; 54 | }kiss_fft_cpx; 55 | 56 | typedef struct kiss_fft_state* kiss_fft_cfg; 57 | 58 | /* 59 | * kiss_fft_alloc 60 | * 61 | * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. 62 | * 63 | * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); 64 | * 65 | * The return value from fft_alloc is a cfg buffer used internally 66 | * by the fft routine or NULL. 67 | * 68 | * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. 69 | * The returned value should be free()d when done to avoid memory leaks. 70 | * 71 | * The state can be placed in a user supplied buffer 'mem': 72 | * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, 73 | * then the function places the cfg in mem and the size used in *lenmem 74 | * and returns mem. 75 | * 76 | * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), 77 | * then the function returns NULL and places the minimum cfg 78 | * buffer size in *lenmem. 79 | * */ 80 | 81 | kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); 82 | 83 | /* 84 | * kiss_fft(cfg,in_out_buf) 85 | * 86 | * Perform an FFT on a complex input buffer. 87 | * for a forward FFT, 88 | * fin should be f[0] , f[1] , ... ,f[nfft-1] 89 | * fout will be F[0] , F[1] , ... ,F[nfft-1] 90 | * Note that each element is complex and can be accessed like 91 | f[k].r and f[k].i 92 | * */ 93 | void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); 94 | 95 | /* 96 | A more generic version of the above function. It reads its input from every Nth sample. 97 | * */ 98 | void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); 99 | 100 | /* If kiss_fft_alloc allocated a buffer, it is one contiguous 101 | buffer and can be simply free()d when no longer needed*/ 102 | #define kiss_fft_free free 103 | 104 | /* 105 | Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up 106 | your compiler output to call this before you exit. 107 | */ 108 | void kiss_fft_cleanup(void); 109 | 110 | 111 | /* 112 | * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) 113 | */ 114 | int kiss_fft_next_fast_size(int n); 115 | 116 | /* for real ffts, we need an even size */ 117 | #define kiss_fftr_next_fast_size_real(n) \ 118 | (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) 119 | 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/codec2/kiss_fftr.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2004, Mark Borgerding 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | */ 14 | 15 | #include "kiss_fftr.h" 16 | #include "_kiss_fft_guts.h" 17 | #include "assert.h" 18 | 19 | struct kiss_fftr_state{ 20 | kiss_fft_cfg substate; 21 | kiss_fft_cpx * tmpbuf; 22 | kiss_fft_cpx * super_twiddles; 23 | #ifdef USE_SIMD 24 | void * pad; 25 | #endif 26 | }; 27 | 28 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) 29 | { 30 | int i; 31 | kiss_fftr_cfg st = NULL; 32 | size_t subsize, memneeded; 33 | 34 | if (nfft & 1) { 35 | fprintf(stderr,"Real FFT optimization must be even.\n"); 36 | return NULL; 37 | } 38 | nfft >>= 1; 39 | 40 | kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); 41 | memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); 42 | 43 | if (lenmem == NULL) { 44 | st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); 45 | } else { 46 | if (*lenmem >= memneeded) 47 | st = (kiss_fftr_cfg) mem; 48 | *lenmem = memneeded; 49 | } 50 | if (!st) 51 | return NULL; 52 | 53 | st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ 54 | st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); 55 | st->super_twiddles = st->tmpbuf + nfft; 56 | kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); 57 | 58 | for (i = 0; i < nfft/2; ++i) { 59 | double phase = 60 | -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); 61 | if (inverse_fft) 62 | phase *= -1; 63 | kf_cexp (st->super_twiddles+i,phase); 64 | } 65 | return st; 66 | } 67 | 68 | void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) 69 | { 70 | /* input buffer timedata is stored row-wise */ 71 | int k,ncfft; 72 | kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; 73 | 74 | assert(st->substate->inverse==0); 75 | 76 | ncfft = st->substate->nfft; 77 | 78 | /*perform the parallel fft of two real signals packed in real,imag*/ 79 | kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); 80 | /* The real part of the DC element of the frequency spectrum in st->tmpbuf 81 | * contains the sum of the even-numbered elements of the input time sequence 82 | * The imag part is the sum of the odd-numbered elements 83 | * 84 | * The sum of tdc.r and tdc.i is the sum of the input time sequence. 85 | * yielding DC of input time sequence 86 | * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... 87 | * yielding Nyquist bin of input time sequence 88 | */ 89 | 90 | tdc.r = st->tmpbuf[0].r; 91 | tdc.i = st->tmpbuf[0].i; 92 | C_FIXDIV(tdc,2); 93 | CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); 94 | CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); 95 | freqdata[0].r = tdc.r + tdc.i; 96 | freqdata[ncfft].r = tdc.r - tdc.i; 97 | #ifdef USE_SIMD 98 | freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); 99 | #else 100 | freqdata[ncfft].i = freqdata[0].i = 0; 101 | #endif 102 | 103 | for ( k=1;k <= ncfft/2 ; ++k ) { 104 | fpk = st->tmpbuf[k]; 105 | fpnk.r = st->tmpbuf[ncfft-k].r; 106 | fpnk.i = - st->tmpbuf[ncfft-k].i; 107 | C_FIXDIV(fpk,2); 108 | C_FIXDIV(fpnk,2); 109 | 110 | C_ADD( f1k, fpk , fpnk ); 111 | C_SUB( f2k, fpk , fpnk ); 112 | C_MUL( tw , f2k , st->super_twiddles[k-1]); 113 | 114 | freqdata[k].r = HALF_OF(f1k.r + tw.r); 115 | freqdata[k].i = HALF_OF(f1k.i + tw.i); 116 | freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); 117 | freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); 118 | } 119 | } 120 | 121 | void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) 122 | { 123 | /* input buffer timedata is stored row-wise */ 124 | int k, ncfft; 125 | 126 | assert(st->substate->inverse == 1); 127 | 128 | ncfft = st->substate->nfft; 129 | 130 | st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; 131 | st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; 132 | C_FIXDIV(st->tmpbuf[0],2); 133 | 134 | for (k = 1; k <= ncfft / 2; ++k) { 135 | kiss_fft_cpx fk, fnkc, fek, fok, tmp; 136 | fk = freqdata[k]; 137 | fnkc.r = freqdata[ncfft - k].r; 138 | fnkc.i = -freqdata[ncfft - k].i; 139 | C_FIXDIV( fk , 2 ); 140 | C_FIXDIV( fnkc , 2 ); 141 | 142 | C_ADD (fek, fk, fnkc); 143 | C_SUB (tmp, fk, fnkc); 144 | C_MUL (fok, tmp, st->super_twiddles[k-1]); 145 | C_ADD (st->tmpbuf[k], fek, fok); 146 | C_SUB (st->tmpbuf[ncfft - k], fek, fok); 147 | #ifdef USE_SIMD 148 | st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); 149 | #else 150 | st->tmpbuf[ncfft - k].i *= -1; 151 | #endif 152 | } 153 | kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); 154 | } 155 | -------------------------------------------------------------------------------- /src/codec2/kiss_fftr.h: -------------------------------------------------------------------------------- 1 | #ifndef KISS_FTR_H 2 | #define KISS_FTR_H 3 | 4 | #include "kiss_fft.h" 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | 10 | /* 11 | 12 | Real optimized version can save about 45% cpu time vs. complex fft of a real seq. 13 | 14 | 15 | 16 | */ 17 | 18 | typedef struct kiss_fftr_state *kiss_fftr_cfg; 19 | 20 | 21 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); 22 | /* 23 | nfft must be even 24 | 25 | If you don't care to allocate space, use mem = lenmem = NULL 26 | */ 27 | 28 | 29 | void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); 30 | /* 31 | input timedata has nfft scalar points 32 | output freqdata has nfft/2+1 complex points 33 | */ 34 | 35 | void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); 36 | /* 37 | input freqdata has nfft/2+1 complex points 38 | output timedata has nfft scalar points 39 | */ 40 | 41 | #define kiss_fftr_free free 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | #endif 47 | -------------------------------------------------------------------------------- /src/codec2/linreg.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: linreg.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: April 2015 6 | 7 | Linear regression C module based on: 8 | 9 | http://stackoverflow.com/questions/5083465/fast-efficient-least-squares-fit-algorithm-in-c 10 | 11 | Use: 12 | 13 | $ gcc linreg.c -o linreg -D__UNITTEST__ -Wall 14 | $ ./linreg 15 | 16 | Then compare yfit results with octave/tlinreg.m 17 | 18 | \*---------------------------------------------------------------------------*/ 19 | 20 | /* 21 | Copyright (C) 2015 David Rowe 22 | 23 | All rights reserved. 24 | 25 | This program is free software; you can redistribute it and/or modify 26 | it under the terms of the GNU Lesser General Public License version 2.1, as 27 | published by the Free Software Foundation. This program is 28 | distributed in the hope that it will be useful, but WITHOUT ANY 29 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 30 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 31 | License for more details. 32 | 33 | You should have received a copy of the GNU Lesser General Public License 34 | along with this program; if not, see . 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include "linreg.h" 42 | #include "comp_prim.h" 43 | 44 | 45 | void linreg(COMP *m, COMP *b, float x[], COMP y[], int n) 46 | { 47 | float sumx = 0.0; /* sum of x */ 48 | float sumx2 = 0.0; /* sum of x^2 */ 49 | COMP sumxy = {0.0,0.0}; /* sum of x * y */ 50 | COMP sumy = {0.0,0.0}; /* sum of y */ 51 | COMP sumy2 = {0.0,0.0}; /* sum of y**2 */ 52 | float denom; 53 | COMP zero; 54 | int i; 55 | 56 | for (i=0; i. 26 | */ 27 | 28 | #ifndef __LINREG__ 29 | #define __LINREG__ 30 | 31 | #include "comp.h" 32 | 33 | void linreg(COMP *m, COMP *b, float x[], COMP y[], int n); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/codec2/lpc.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: lpc.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 24/8/09 6 | 7 | Linear Prediction functions written in C. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009-2012 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __LPC__ 29 | #define __LPC__ 30 | 31 | #define LPC_MAX_ORDER 20 32 | 33 | void pre_emp(float Sn_pre[], float Sn[], float *mem, int Nsam); 34 | void de_emp(float Sn_se[], float Sn[], float *mem, int Nsam); 35 | void hanning_window(float Sn[], float Wn[], int Nsam); 36 | void autocorrelate(float Sn[], float Rn[], int Nsam, int order); 37 | void levinson_durbin(float R[], float lpcs[], int order); 38 | void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); 39 | void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); 40 | void find_aks(float Sn[], float a[], int Nsam, int order, float *E); 41 | void weight(float ak[], float gamma, int order, float akw[]); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/codec2/lsp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: lsp.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 24/2/93 6 | 7 | 8 | This file contains functions for LPC to LSP conversion and LSP to 9 | LPC conversion. Note that the LSP coefficients are not in radians 10 | format but in the x domain of the unit circle. 11 | 12 | \*---------------------------------------------------------------------------*/ 13 | 14 | /* 15 | Copyright (C) 2009 David Rowe 16 | 17 | All rights reserved. 18 | 19 | This program is free software; you can redistribute it and/or modify 20 | it under the terms of the GNU Lesser General Public License version 2.1, as 21 | published by the Free Software Foundation. This program is 22 | distributed in the hope that it will be useful, but WITHOUT ANY 23 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 24 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 25 | License for more details. 26 | 27 | You should have received a copy of the GNU Lesser General Public License 28 | along with this program; if not, see . 29 | */ 30 | 31 | #ifndef __LSP__ 32 | #define __LSP__ 33 | 34 | int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta); 35 | void lsp_to_lpc(float *freq, float *ak, int lpcrdr); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/codec2/machdep.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: machdep.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: May 2 2013 6 | 7 | Machine dependant functions, e.g. profiling that requires access to a clock 8 | counter register. 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright (C) 2013 David Rowe 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | */ 28 | 29 | #ifndef __MACHDEP__ 30 | #define __MACHDEP__ 31 | 32 | #ifdef PROFILE 33 | #define PROFILE_VAR(...) unsigned int __VA_ARGS__ 34 | #define PROFILE_SAMPLE(timestamp) timestamp = machdep_profile_sample() 35 | #define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) \ 36 | timestamp = machdep_profile_sample_and_log(prev_timestamp, label) 37 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) \ 38 | machdep_profile_sample_and_log(prev_timestamp, label) 39 | #else 40 | #define PROFILE_VAR(...) 41 | #define PROFILE_SAMPLE(timestamp) 42 | #define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) 43 | #define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) 44 | #endif 45 | 46 | void machdep_profile_init(void); 47 | void machdep_profile_reset(void); 48 | unsigned int machdep_profile_sample(void); 49 | unsigned int machdep_profile_sample_and_log(unsigned int start, char s[]); 50 | void machdep_profile_print_logged_samples(void); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/codec2/mbest.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: mbest.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: Jan 2017 6 | 7 | Multistage vector quantiser search algorithm that keeps multiple 8 | candidates from each stage. 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright David Rowe 2017 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "mbest.h" 37 | 38 | struct MBEST *mbest_create(int entries) { 39 | int i,j; 40 | struct MBEST *mbest; 41 | 42 | assert(entries > 0); 43 | mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); 44 | assert(mbest != NULL); 45 | 46 | mbest->entries = entries; 47 | mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); 48 | assert(mbest->list != NULL); 49 | 50 | for(i=0; ientries; i++) { 51 | for(j=0; jlist[i].index[j] = 0; 53 | mbest->list[i].error = 1E32; 54 | } 55 | 56 | return mbest; 57 | } 58 | 59 | 60 | void mbest_destroy(struct MBEST *mbest) { 61 | assert(mbest != NULL); 62 | free(mbest->list); 63 | free(mbest); 64 | } 65 | 66 | 67 | /*---------------------------------------------------------------------------*\ 68 | 69 | mbest_insert 70 | 71 | Insert the results of a vector to codebook entry comparison. The 72 | list is ordered in order or error, so those entries with the 73 | smallest error will be first on the list. 74 | 75 | \*---------------------------------------------------------------------------*/ 76 | 77 | void mbest_insert(struct MBEST *mbest, int index[], float error) { 78 | int i, j, found; 79 | struct MBEST_LIST *list = mbest->list; 80 | int entries = mbest->entries; 81 | 82 | found = 0; 83 | for(i=0; ii; j--) 87 | list[j] = list[j-1]; 88 | for(j=0; jentries; i++) { 101 | for(j=0; jlist[i].index[j]); 103 | fprintf(stderr, " %f\n", mbest->list[i].error); 104 | } 105 | } 106 | #endif 107 | 108 | 109 | /*---------------------------------------------------------------------------*\ 110 | 111 | mbest_search 112 | 113 | Searches vec[] to a codebbook of vectors, and maintains a list of the mbest 114 | closest matches. 115 | 116 | \*---------------------------------------------------------------------------*/ 117 | 118 | void mbest_search( 119 | const float *cb, /* VQ codebook to search */ 120 | float vec[], /* target vector */ 121 | float w[], /* weighting vector */ 122 | int k, /* dimension of vector */ 123 | int m, /* number on entries in codebook */ 124 | struct MBEST *mbest, /* list of closest matches */ 125 | int index[] /* indexes that lead us here */ 126 | ) 127 | { 128 | float e; 129 | int i,j; 130 | float diff; 131 | 132 | for(j=0; j. 27 | 28 | */ 29 | 30 | #ifndef __MBEST__ 31 | #define __MBEST__ 32 | 33 | #define MBEST_STAGES 4 34 | 35 | struct MBEST_LIST { 36 | int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ 37 | float error; 38 | }; 39 | 40 | struct MBEST { 41 | int entries; /* number of entries in mbest list */ 42 | struct MBEST_LIST *list; 43 | }; 44 | 45 | struct MBEST *mbest_create(int entries); 46 | void mbest_destroy(struct MBEST *mbest); 47 | void mbest_insert(struct MBEST *mbest, int index[], float error); 48 | void mbest_search(const float *cb, float vec[], float w[], int k, int m, struct MBEST *mbest, int index[]); 49 | 50 | // #define MBEST_PRINT_OUT 51 | #ifdef MBEST_PRINT_OUT 52 | #define MBEST_PRINT(a,b) mbest_print((a),(b)) 53 | #else 54 | #define MBEST_PRINT(a,b) 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/codec2/modem_probe.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: modem_probe.c 4 | AUTHOR......: Brady O'Brien 5 | DATE CREATED: 9 January 2016 6 | 7 | Library to easily extract debug traces from modems during development and 8 | verification 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | /* 13 | Copyright (C) 2016 David Rowe 14 | 15 | All rights reserved. 16 | 17 | This program is free software; you can redistribute it and/or modify 18 | it under the terms of the GNU Lesser General Public License version 2.1, as 19 | published by the Free Software Foundation. This program is 20 | distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 22 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 23 | License for more details. 24 | 25 | You should have received a copy of the GNU Lesser General Public License 26 | along with this program; if not, see . 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "comp.h" 34 | #include "octave.h" 35 | 36 | #define TRACE_I 1 37 | #define TRACE_F 2 38 | #define TRACE_C 3 39 | 40 | 41 | typedef struct probe_trace_info_s probe_trace_info; 42 | typedef struct datlink_s datlink; 43 | 44 | struct datlink_s{ 45 | void * data; 46 | size_t len; 47 | datlink * next; 48 | }; 49 | 50 | struct probe_trace_info_s{ 51 | int type; 52 | char name[255]; 53 | datlink * data; 54 | datlink * last; 55 | probe_trace_info *next; 56 | }; 57 | 58 | static char *run = NULL; 59 | static char *mod = NULL; 60 | static probe_trace_info *first_trace = NULL; 61 | 62 | /* Init the probing library */ 63 | void modem_probe_init_int(char *modname, char *runname){ 64 | mod = malloc((strlen(modname)+1)*sizeof(char)); 65 | run = malloc((strlen(runname)+1)*sizeof(char)); 66 | strcpy(run,runname); 67 | strcpy(mod,modname); 68 | } 69 | 70 | /* 71 | * Gather the data stored in the linked list into a single blob, 72 | * freeing links and buffers as it goes 73 | */ 74 | void * gather_data(datlink * d,size_t * len){ 75 | size_t size = 0; 76 | datlink * cur = d; 77 | datlink * next; 78 | while(cur!=NULL){ 79 | size += d->len; 80 | cur = cur->next; 81 | } 82 | cur = d; 83 | size_t i = 0; 84 | void * newbuf = malloc(size); 85 | 86 | while(cur!=NULL){ 87 | memcpy(newbuf+i,cur->data,cur->len); 88 | i += cur->len; 89 | free(cur->data); 90 | next = cur->next; 91 | free(cur); 92 | cur = next; 93 | } 94 | *len = size; 95 | return newbuf; 96 | } 97 | 98 | /* Dump all of the traces into a nice octave-able dump file */ 99 | void modem_probe_close_int(){ 100 | if(run==NULL) 101 | return; 102 | 103 | probe_trace_info *cur,*next; 104 | cur = first_trace; 105 | FILE * dumpfile = fopen(run,"w"); 106 | void * dbuf; 107 | size_t len; 108 | 109 | while(cur != NULL){ 110 | dbuf = gather_data(cur->data,&len); 111 | switch(cur->type){ 112 | case TRACE_I: 113 | octave_save_int(dumpfile,cur->name,(int32_t*)dbuf,1,len/sizeof(int32_t)); 114 | break; 115 | case TRACE_F: 116 | octave_save_float(dumpfile,cur->name,(float*)dbuf,1,len/sizeof(float),10); 117 | break; 118 | case TRACE_C: 119 | octave_save_complex(dumpfile,cur->name,(COMP*)dbuf,1,len/sizeof(COMP),10); 120 | break; 121 | } 122 | next = cur->next; 123 | free(cur); 124 | free(dbuf); 125 | cur = next; 126 | } 127 | 128 | fclose(dumpfile); 129 | free(run); 130 | free(mod); 131 | } 132 | 133 | /* Look up or create a trace by name */ 134 | probe_trace_info * modem_probe_get_trace(char * tracename){ 135 | probe_trace_info *cur,*npti; 136 | 137 | /* Make sure probe session is open */ 138 | if(run==NULL) 139 | return NULL; 140 | 141 | cur = first_trace; 142 | /* Walk through list, find trace with matching name */ 143 | while(cur != NULL){ 144 | /* We got one! */ 145 | if(strcmp( cur->name, tracename) == 0){ 146 | return cur; 147 | } 148 | cur = cur->next; 149 | } 150 | /* None found, open a new trace */ 151 | 152 | npti = (probe_trace_info *) malloc(sizeof(probe_trace_info)); 153 | npti->next = first_trace; 154 | npti->data = NULL; 155 | npti->last = NULL; 156 | strcpy(npti->name,tracename); 157 | first_trace = npti; 158 | 159 | return npti; 160 | 161 | } 162 | 163 | void modem_probe_samp_i_int(char * tracename,int32_t samp[],size_t cnt){ 164 | probe_trace_info *pti; 165 | datlink *ndat; 166 | 167 | pti = modem_probe_get_trace(tracename); 168 | if(pti == NULL) 169 | return; 170 | 171 | pti->type = TRACE_I; 172 | 173 | ndat = (datlink*) malloc(sizeof(datlink)); 174 | ndat->data = malloc(sizeof(int32_t)*cnt); 175 | 176 | ndat->len = cnt*sizeof(int32_t); 177 | ndat->next = NULL; 178 | memcpy(ndat->data,(void*)&(samp[0]),sizeof(int32_t)*cnt); 179 | 180 | if(pti->last!=NULL){ 181 | pti->last->next = ndat; 182 | pti->last = ndat; 183 | } else { 184 | pti->data = ndat; 185 | pti->last = ndat; 186 | } 187 | 188 | } 189 | 190 | void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt){ 191 | probe_trace_info *pti; 192 | datlink *ndat; 193 | 194 | pti = modem_probe_get_trace(tracename); 195 | if(pti == NULL) 196 | return; 197 | 198 | pti->type = TRACE_F; 199 | 200 | ndat = (datlink*) malloc(sizeof(datlink)); 201 | ndat->data = malloc(sizeof(float)*cnt); 202 | 203 | ndat->len = cnt*sizeof(float); 204 | ndat->next = NULL; 205 | memcpy(ndat->data,(void*)&(samp[0]),sizeof(float)*cnt); 206 | 207 | if(pti->last!=NULL){ 208 | pti->last->next = ndat; 209 | pti->last = ndat; 210 | } else { 211 | pti->data = ndat; 212 | pti->last = ndat; 213 | } 214 | } 215 | 216 | void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt){ 217 | probe_trace_info *pti; 218 | datlink *ndat; 219 | 220 | pti = modem_probe_get_trace(tracename); 221 | if(pti == NULL) 222 | return; 223 | 224 | pti->type = TRACE_C; 225 | 226 | ndat = (datlink*) malloc(sizeof(datlink)); 227 | ndat->data = malloc(sizeof(COMP)*cnt); 228 | 229 | ndat->len = cnt*sizeof(COMP); 230 | ndat->next = NULL; 231 | memcpy(ndat->data,(void*)&(samp[0]),sizeof(COMP)*cnt); 232 | 233 | if(pti->last!=NULL){ 234 | pti->last->next = ndat; 235 | pti->last = ndat; 236 | } else { 237 | pti->data = ndat; 238 | pti->last = ndat; 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/codec2/modem_probe.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: modem_probe.h 4 | AUTHOR......: Brady O'Brien 5 | DATE CREATED: 9 January 2016 6 | 7 | Library to easily extract debug traces from modems during development 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2016 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __MODEMPROBE_H 29 | #define __MODEMPROBE_H 30 | #include 31 | #include 32 | #include "comp.h" 33 | 34 | 35 | #ifdef MODEMPROBE_ENABLE 36 | 37 | /* Internal functions */ 38 | void modem_probe_init_int(char *modname, char *runname); 39 | void modem_probe_close_int(); 40 | 41 | void modem_probe_samp_i_int(char * tracename,int samp[],size_t cnt); 42 | void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt); 43 | void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt); 44 | 45 | /* 46 | * Init the probe library. 47 | * char *modname - Name of the modem under test 48 | * char *runname - Name/path of the file data is dumped to 49 | */ 50 | static inline void modem_probe_init(char *modname,char *runname){ 51 | modem_probe_init_int(modname,runname); 52 | } 53 | 54 | /* 55 | * Dump traces to a file and clean up 56 | */ 57 | static inline void modem_probe_close(){ 58 | modem_probe_close_int(); 59 | } 60 | 61 | /* 62 | * Save some number of int samples to a named trace 63 | * char *tracename - name of trace being saved to 64 | * int samp[] - int samples 65 | * size_t cnt - how many samples to save 66 | */ 67 | static inline void modem_probe_samp_i(char *tracename,int samp[],size_t cnt){ 68 | modem_probe_samp_i_int(tracename,samp,cnt); 69 | } 70 | 71 | /* 72 | * Save some number of float samples to a named trace 73 | * char *tracename - name of trace being saved to 74 | * float samp[] - int samples 75 | * size_t cnt - how many samples to save 76 | */ 77 | static inline void modem_probe_samp_f(char *tracename,float samp[],size_t cnt){ 78 | modem_probe_samp_f_int(tracename,samp,cnt); 79 | } 80 | 81 | /* 82 | * Save some number of complex samples to a named trace 83 | * char *tracename - name of trace being saved to 84 | * COMP samp[] - int samples 85 | * size_t cnt - how many samples to save 86 | */ 87 | static inline void modem_probe_samp_c(char *tracename,COMP samp[],size_t cnt){ 88 | modem_probe_samp_c_int(tracename,samp,cnt); 89 | } 90 | 91 | #else 92 | 93 | static inline void modem_probe_init(char *modname,char *runname){ 94 | return; 95 | } 96 | 97 | static inline void modem_probe_close(){ 98 | return; 99 | } 100 | 101 | static inline void modem_probe_samp_i(char *name,int samp[],size_t sampcnt){ 102 | return; 103 | } 104 | 105 | static inline void modem_probe_samp_f(char *name,float samp[],size_t cnt){ 106 | return; 107 | } 108 | 109 | static inline void modem_probe_samp_c(char *name,COMP samp[],size_t cnt){ 110 | return; 111 | } 112 | 113 | #endif 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/codec2/modem_stats.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: modem_stats.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: June 2015 6 | 7 | Common functions for returning demod stats from fdmdv and cohpsk modems. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2015 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #include 29 | #include 30 | #include "modem_stats.h" 31 | #include "codec2_fdmdv.h" 32 | 33 | void modem_stats_open(struct MODEM_STATS *f) 34 | { 35 | int i; 36 | 37 | for(i=0; i<2*MODEM_STATS_NSPEC; i++) 38 | f->fft_buf[i] = 0.0; 39 | f->fft_cfg = kiss_fft_alloc (2*MODEM_STATS_NSPEC, 0, NULL, NULL); 40 | assert(f->fft_cfg != NULL); 41 | } 42 | 43 | void modem_stats_close(struct MODEM_STATS *f) 44 | { 45 | KISS_FFT_FREE(f->fft_cfg); 46 | } 47 | 48 | /*---------------------------------------------------------------------------*\ 49 | 50 | FUNCTION....: modem_stats_get_rx_spectrum() 51 | AUTHOR......: David Rowe 52 | DATE CREATED: 9 June 2012 53 | 54 | Returns the MODEM_STATS_NSPEC point magnitude spectrum of the rx signal in 55 | dB. The spectral samples are scaled so that 0dB is the peak, a good 56 | range for plotting is 0 to -40dB. 57 | 58 | Note only the real part of the complex input signal is used at 59 | present. A complex variable is used for input for compatability 60 | with the other rx signal procesing. 61 | 62 | Successive calls can be used to build up a waterfall or spectrogram 63 | plot, by mapping the received levels to colours. 64 | 65 | The time-frequency resolution of the spectrum can be adjusted by varying 66 | MODEM_STATS_NSPEC. Note that a 2* MODEM_STATS_NSPEC size FFT is reqd to get 67 | MODEM_STATS_NSPEC output points. MODEM_STATS_NSPEC must be a power of 2. 68 | 69 | See octave/tget_spec.m for a demo real time spectral display using 70 | Octave. This demo averages the output over time to get a smoother 71 | display: 72 | 73 | av = 0.9*av + 0.1*mag_dB 74 | 75 | \*---------------------------------------------------------------------------*/ 76 | 77 | void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin) 78 | { 79 | int i,j; 80 | COMP fft_in[2*MODEM_STATS_NSPEC]; 81 | COMP fft_out[2*MODEM_STATS_NSPEC]; 82 | float full_scale_dB; 83 | 84 | /* update buffer of input samples */ 85 | 86 | for(i=0; i<2*MODEM_STATS_NSPEC-nin; i++) 87 | f->fft_buf[i] = f->fft_buf[i+nin]; 88 | for(j=0; jfft_buf[i] = rx_fdm[j].real; 90 | assert(i == 2*MODEM_STATS_NSPEC); 91 | 92 | /* window and FFT */ 93 | 94 | for(i=0; i<2*MODEM_STATS_NSPEC; i++) { 95 | fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cosf((float)i*2.0*M_PI/(2*MODEM_STATS_NSPEC))); 96 | fft_in[i].imag = 0.0; 97 | } 98 | 99 | kiss_fft(f->fft_cfg, (kiss_fft_cpx *)fft_in, (kiss_fft_cpx *)fft_out); 100 | 101 | /* FFT scales up a signal of level 1 FDMDV_NSPEC */ 102 | 103 | full_scale_dB = 20*log10(MODEM_STATS_NSPEC*FDMDV_SCALE); 104 | 105 | /* scale and convert to dB */ 106 | 107 | for(i=0; i. 26 | */ 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #ifndef __MODEM_STATS__ 33 | #define __MODEM_STATS__ 34 | 35 | #include "comp.h" 36 | #include "kiss_fft.h" 37 | 38 | #define MODEM_STATS_NC_MAX 20 39 | #define MODEM_STATS_NR_MAX 6 40 | #define MODEM_STATS_ET_MAX 8 41 | #define MODEM_STATS_NSPEC 512 42 | #define MODEM_STATS_MAX_F_HZ 4000 43 | 44 | struct MODEM_STATS { 45 | int Nc; 46 | float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ 47 | COMP rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX+1]; 48 | /* latest received symbols, for scatter plot */ 49 | int nr; /* number of rows in rx_symbols */ 50 | int sync; /* demod sync state */ 51 | float foff; /* estimated freq offset in Hz */ 52 | float rx_timing; /* estimated optimum timing offset in samples */ 53 | float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ 54 | 55 | /* eye diagram traces */ 56 | /* Eye diagram plot -- first dim is trace number, second is the trace idx */ 57 | float rx_eye[MODEM_STATS_ET_MAX][80]; 58 | int neyetr; /* How many eye traces are plotted */ 59 | int neyesamp; /* How many samples in the eye diagram */ 60 | 61 | /* Buf for FFT/waterfall */ 62 | 63 | float fft_buf[2*MODEM_STATS_NSPEC]; 64 | kiss_fft_cfg fft_cfg; 65 | }; 66 | 67 | void modem_stats_open(struct MODEM_STATS *f); 68 | void modem_stats_close(struct MODEM_STATS *f); 69 | void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin); 70 | 71 | #endif 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | -------------------------------------------------------------------------------- /src/codec2/mpdecode_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | FILE...: mpdecode_core.h 3 | AUTHOR.: David Rowe 4 | CREATED: Sep 2016 5 | 6 | C-callable core functions for MpDecode, so they can be used for 7 | Octave and C programs. Also some convenience functions to help use 8 | the C-callable LDPC decoder in C programs. 9 | */ 10 | 11 | #ifndef __MPDECODE_CORE__ 12 | #define __MPDECODE_CORE__ 13 | 14 | struct LDPC { 15 | int max_iter; 16 | int dec_type; 17 | int q_scale_factor; 18 | int r_scale_factor; 19 | int CodeLength; 20 | int NumberParityBits; 21 | int NumberRowsHcols; 22 | int max_row_weight; 23 | int max_col_weight; 24 | double *H_rows; 25 | double *H_cols; 26 | }; 27 | 28 | int run_ldpc_decoder(struct LDPC *ldpc, char out_char[], double input[]); 29 | 30 | void sd_to_llr(double llr[], double sd[], int n); 31 | 32 | struct v_node { 33 | int degree; 34 | float initial_value; 35 | int *index; /* the index of a c_node it is connected to */ 36 | int *socket; /* socket number at the c_node */ 37 | float *message; 38 | int *sign; 39 | }; 40 | 41 | struct c_node { 42 | int degree; 43 | int *index; 44 | float *message; 45 | int *socket; /* socket number at the v_node */ 46 | }; 47 | 48 | void init_c_v_nodes(struct c_node *c_nodes, 49 | int shift, 50 | int NumberParityBits, 51 | int max_row_weight, 52 | double *H_rows, 53 | int H1, 54 | int CodeLength, 55 | struct v_node *v_nodes, 56 | int NumberRowsHcols, 57 | double *H_cols, 58 | int max_col_weight, 59 | int dec_type, 60 | double *input); 61 | 62 | void ApproximateMinStar( int BitErrors[], 63 | int DecodedBits[], 64 | struct c_node c_nodes[], 65 | struct v_node v_nodes[], 66 | int CodeLength, 67 | int NumberParityBits, 68 | int max_iter ); 69 | 70 | void MinSum( int BitErrors[], 71 | int DecodedBits[], 72 | struct c_node c_nodes[], 73 | struct v_node v_nodes[], 74 | int CodeLength, 75 | int NumberParityBits, 76 | int max_iter, 77 | float r_scale_factor, 78 | float q_scale_factor, 79 | int data[] ); 80 | 81 | 82 | void SumProduct( int BitErrors[], 83 | int DecodedBits[], 84 | struct c_node c_nodes[], 85 | struct v_node v_nodes[], 86 | int CodeLength, 87 | int NumberParityBits, 88 | int max_iter, 89 | float r_scale_factor, 90 | float q_scale_factor, 91 | int data[]); 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/codec2/nlp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: nlp.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 23/3/93 6 | 7 | Non Linear Pitch (NLP) estimation functions. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __NLP__ 29 | #define __NLP__ 30 | 31 | #include "comp.h" 32 | 33 | void *nlp_create(C2CONST *c2const); 34 | void nlp_destroy(void *nlp_state); 35 | float nlp(void *nlp_state, float Sn[], int n, 36 | float *pitch_samples, COMP Sw[], COMP W[], float *prev_f0); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/codec2/octave.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: octave.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: April 28 2012 6 | 7 | Functions to save C arrays in GNU Octave matrix format. The output text 8 | file can be directly read into Octave using "load filename". 9 | 10 | \*---------------------------------------------------------------------------*/ 11 | 12 | 13 | /* 14 | Copyright (C) 2012 David Rowe 15 | 16 | All rights reserved. 17 | 18 | This program is free software; you can redistribute it and/or modify 19 | it under the terms of the GNU Lesser General Public License version 2, as 20 | published by the Free Software Foundation. This program is 21 | distributed in the hope that it will be useful, but WITHOUT ANY 22 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 24 | License for more details. 25 | 26 | You should have received a copy of the GNU Lesser General Public License 27 | along with this program; if not, see . 28 | */ 29 | 30 | #include 31 | #include 32 | 33 | #include "octave.h" 34 | 35 | #ifdef ARM_MATH_CM4 36 | #include "Trace.h" 37 | #endif 38 | 39 | #define OCTAVE_BUFSIZE 2048 40 | 41 | 42 | void flush_buffer(FILE* f, char* buffer,size_t* buf_idx_ptr) 43 | { 44 | #ifdef ARM_MATH_CM4 45 | trace_write(buffer,*buf_idx_ptr); 46 | #else 47 | fwrite(buffer,*buf_idx_ptr,1,f); 48 | #endif 49 | *buf_idx_ptr = 0; 50 | } 51 | 52 | void handle_buffer(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, size_t l) 53 | { 54 | *buf_idx_ptr += l; 55 | if (*buf_idx_ptr > max_buf - 64) 56 | { 57 | flush_buffer(f, buffer,buf_idx_ptr); 58 | } 59 | } 60 | 61 | signed int printf_buffer(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, const char *pFormat, ...) 62 | { 63 | va_list ap; 64 | signed int rc; 65 | 66 | va_start(ap, pFormat); 67 | rc = vsnprintf(&buffer[*buf_idx_ptr], max_buf - *buf_idx_ptr, pFormat, ap); 68 | va_end(ap); 69 | if (rc>0) 70 | { 71 | handle_buffer(f, buffer,max_buf,buf_idx_ptr,rc); 72 | } 73 | return rc; 74 | } 75 | 76 | 77 | void printf_header(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, const char *name, const char *dtype, int rows, int cols, int isFloat) 78 | { 79 | #ifdef ARM_MATH_CM4 80 | printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# hex: %s\n", isFloat?"true":"false"); 81 | #endif 82 | printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# name: %s\n", name); 83 | printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# type: %s\n",dtype); 84 | printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# rows: %d\n", rows); 85 | printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# columns: %d\n", cols); 86 | } 87 | void octave_save_int(FILE *f, char name[], int data[], int rows, int cols) 88 | { 89 | int r,c; 90 | char buffer[OCTAVE_BUFSIZE]; 91 | size_t buf_idx = 0; 92 | 93 | printf_header(f, buffer, OCTAVE_BUFSIZE, &buf_idx, name, "matrix", rows, cols, 0); 94 | 95 | for(r=0; r. 28 | */ 29 | 30 | #ifndef __OCTAVE__ 31 | #define __OCTAVE__ 32 | 33 | #include "comp.h" 34 | 35 | void octave_save_int(FILE *f, char name[], int data[], int rows, int cols); 36 | void octave_save_float(FILE *f, char name[], float data[], int rows, int cols, int col_len); 37 | void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/codec2/ofdm_internal.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: ofdm_internal.h 4 | AUTHORS.....: David Rowe & Steve Sampson 5 | DATE CREATED: June 2017 6 | 7 | OFDM Internal definitions. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2017 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef OFDM_INTERNAL_H 29 | #define OFDM_INTERNAL_H 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #include 36 | #include 37 | 38 | #ifndef M_PI 39 | #define M_PI 3.14159265358979323846f /* math constant */ 40 | #endif 41 | 42 | #define TAU (2.0f * M_PI) /* mathematical constant */ 43 | 44 | #define OFDM_NC 16 45 | #define OFDM_TS 0.018f 46 | #define OFDM_RS (1.0f / OFDM_TS) 47 | #define OFDM_FS 8000.0f 48 | #define OFDM_BPS 2 49 | #define OFDM_TCP 0.002f 50 | #define OFDM_NS 8 51 | #define OFDM_CENTRE 1500.0f 52 | 53 | /* To prevent C99 warning */ 54 | 55 | #define OFDM_M 144 56 | #define OFDM_NCP 16 57 | 58 | #ifdef OLD_STYLE 59 | /* This will produce a warning in C99 as (int) makes these variable */ 60 | 61 | #define OFDM_M ((int)(OFDM_FS / OFDM_RS)) 62 | #define OFDM_NCP ((int)(OFDM_TCP * OFDM_FS)) 63 | #endif 64 | 65 | #define OFDM_FTWINDOWWIDTH 11 66 | #define OFDM_BITSPERFRAME ((OFDM_NS - 1) * (OFDM_NC * OFDM_BPS)) 67 | #define OFDM_ROWSPERFRAME (OFDM_BITSPERFRAME / (OFDM_NC * OFDM_BPS)) 68 | #define OFDM_SAMPLESPERFRAME (OFDM_NS * (OFDM_M + OFDM_NCP)) 69 | #define OFDM_MAX_SAMPLESPERFRAME (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP)/4) 70 | #define OFDM_RXBUF (3 * OFDM_SAMPLESPERFRAME + 3 * (OFDM_M + OFDM_NCP)) 71 | 72 | struct OFDM { 73 | float foff_est_gain; 74 | float foff_est_hz; 75 | 76 | int verbose; 77 | int sample_point; 78 | int timing_est; 79 | int nin; 80 | 81 | bool timing_en; 82 | bool foff_est_en; 83 | bool phase_est_en; 84 | 85 | complex float pilot_samples[OFDM_M + OFDM_NCP]; 86 | complex float W[OFDM_NC + 2][OFDM_M]; 87 | complex float rxbuf[OFDM_RXBUF]; 88 | complex float pilots[OFDM_NC + 2]; 89 | float w[OFDM_NC + 2]; 90 | 91 | /* Demodulator data */ 92 | 93 | complex float rx_sym[OFDM_NS + 3][OFDM_NC + 2]; 94 | complex float rx_np[OFDM_ROWSPERFRAME * OFDM_NC]; 95 | float rx_amp[OFDM_ROWSPERFRAME * OFDM_NC]; 96 | float aphase_est_pilot_log[OFDM_ROWSPERFRAME * OFDM_NC]; 97 | }; 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/codec2/os.h: -------------------------------------------------------------------------------- 1 | /* Generate using fir1(47,1/2) in Octave */ 2 | 3 | static const float fdmdv_os_filter[]= { 4 | -0.0008215855034550382, 5 | -0.0007833023901802921, 6 | 0.001075563790768233, 7 | 0.001199092367787555, 8 | -0.001765309502928316, 9 | -0.002055372115328064, 10 | 0.002986877604154257, 11 | 0.003462567920638414, 12 | -0.004856570111126334, 13 | -0.005563143845031497, 14 | 0.007533613299748122, 15 | 0.008563932468880897, 16 | -0.01126857129039911, 17 | -0.01280782411693687, 18 | 0.01651443896361847, 19 | 0.01894875110322284, 20 | -0.02421604439474981, 21 | -0.02845107338464062, 22 | 0.03672973563400258, 23 | 0.04542046150312214, 24 | -0.06189165826716491, 25 | -0.08721876380763803, 26 | 0.1496157094199961, 27 | 0.4497962274137046, 28 | 0.4497962274137046, 29 | 0.1496157094199961, 30 | -0.08721876380763803, 31 | -0.0618916582671649, 32 | 0.04542046150312216, 33 | 0.03672973563400257, 34 | -0.02845107338464062, 35 | -0.02421604439474984, 36 | 0.01894875110322284, 37 | 0.01651443896361848, 38 | -0.01280782411693687, 39 | -0.0112685712903991, 40 | 0.008563932468880899, 41 | 0.007533613299748123, 42 | -0.005563143845031501, 43 | -0.004856570111126346, 44 | 0.003462567920638419, 45 | 0.002986877604154259, 46 | -0.002055372115328063, 47 | -0.001765309502928318, 48 | 0.001199092367787557, 49 | 0.001075563790768233, 50 | -0.0007833023901802925, 51 | -0.0008215855034550383 52 | }; 53 | 54 | -------------------------------------------------------------------------------- /src/codec2/pack.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2010 Perens LLC 3 | 4 | All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License version 2.1, as 8 | published by the Free Software Foundation. This program is 9 | distributed in the hope that it will be useful, but WITHOUT ANY 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 12 | License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include "defines.h" 19 | #include "quantise.h" 20 | #include 21 | 22 | /* Compile-time constants */ 23 | /* Size of unsigned char in bits. Assumes 8 bits-per-char. */ 24 | static const unsigned int WordSize = 8; 25 | 26 | /* Mask to pick the bit component out of bitIndex. */ 27 | static const unsigned int IndexMask = 0x7; 28 | 29 | /* Used to pick the word component out of bitIndex. */ 30 | static const unsigned int ShiftRight = 3; 31 | 32 | /** Pack a bit field into a bit string, encoding the field in Gray code. 33 | * 34 | * The output is an array of unsigned char data. The fields are efficiently 35 | * packed into the bit string. The Gray coding is a naive attempt to reduce 36 | * the effect of single-bit errors, we expect to do a better job as the 37 | * codec develops. 38 | * 39 | * This code would be simpler if it just set one bit at a time in the string, 40 | * but would hit the same cache line more often. I'm not sure the complexity 41 | * gains us anything here. 42 | * 43 | * Although field is currently of int type rather than unsigned for 44 | * compatibility with the rest of the code, indices are always expected to 45 | * be >= 0. 46 | */ 47 | void 48 | pack( 49 | unsigned char * bitArray, /* The output bit string. */ 50 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ 51 | int field, /* The bit field to be packed. */ 52 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ 53 | ) 54 | { 55 | pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1); 56 | } 57 | 58 | void 59 | pack_natural_or_gray( 60 | unsigned char * bitArray, /* The output bit string. */ 61 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ 62 | int field, /* The bit field to be packed. */ 63 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ 64 | unsigned int gray /* non-zero for gray coding */ 65 | ) 66 | { 67 | if (gray) { 68 | /* Convert the field to Gray code */ 69 | field = (field >> 1) ^ field; 70 | } 71 | 72 | do { 73 | unsigned int bI = *bitIndex; 74 | unsigned int bitsLeft = WordSize - (bI & IndexMask); 75 | unsigned int sliceWidth = 76 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; 77 | unsigned int wordIndex = bI >> ShiftRight; 78 | 79 | bitArray[wordIndex] |= 80 | ((unsigned char)((field >> (fieldWidth - sliceWidth)) 81 | << (bitsLeft - sliceWidth))); 82 | 83 | *bitIndex = bI + sliceWidth; 84 | fieldWidth -= sliceWidth; 85 | } while ( fieldWidth != 0 ); 86 | } 87 | 88 | /** Unpack a field from a bit string, converting from Gray code to binary. 89 | * 90 | */ 91 | int 92 | unpack( 93 | const unsigned char * bitArray, /* The input bit string. */ 94 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ 95 | unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ 96 | ) 97 | { 98 | return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1); 99 | } 100 | 101 | /** Unpack a field from a bit string, to binary, optionally using 102 | * natural or Gray code. 103 | * 104 | */ 105 | int 106 | unpack_natural_or_gray( 107 | const unsigned char * bitArray, /* The input bit string. */ 108 | unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ 109 | unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */ 110 | unsigned int gray /* non-zero for Gray coding */ 111 | ) 112 | { 113 | unsigned int field = 0; 114 | unsigned int t; 115 | 116 | do { 117 | unsigned int bI = *bitIndex; 118 | unsigned int bitsLeft = WordSize - (bI & IndexMask); 119 | unsigned int sliceWidth = 120 | bitsLeft < fieldWidth ? bitsLeft : fieldWidth; 121 | 122 | field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth)); 123 | 124 | *bitIndex = bI + sliceWidth; 125 | fieldWidth -= sliceWidth; 126 | } while ( fieldWidth != 0 ); 127 | 128 | if (gray) { 129 | /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ 130 | t = field ^ (field >> 8); 131 | t ^= (t >> 4); 132 | t ^= (t >> 2); 133 | t ^= (t >> 1); 134 | } 135 | else { 136 | t = field; 137 | } 138 | 139 | return t; 140 | } 141 | -------------------------------------------------------------------------------- /src/codec2/phase.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: phase.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 1/2/09 6 | 7 | Functions for modelling phase. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __PHASE__ 29 | #define __PHASE__ 30 | 31 | #include "codec2_fft.h" 32 | #include "comp.h" 33 | 34 | void sample_phase(MODEL *model, COMP filter_phase[], COMP A[]); 35 | void phase_synth_zero_order(int n_samp, MODEL *model, float *ex_phase, COMP filter_phase[]); 36 | 37 | void mag_to_phase(float phase[], float Gdbfk[], int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/codec2/phaseexp.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: phaseexp.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: June 2012 6 | 7 | Experimental functions for quantising, modelling and synthesising phase. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2012 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __PHASEEXP__ 29 | #define __PHASEEXP__ 30 | 31 | #include "kiss_fft.h" 32 | 33 | struct PEXP; 34 | 35 | struct PEXP * phase_experiment_create(); 36 | void phase_experiment_destroy(struct PEXP *pexp); 37 | void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/codec2/pilot_coeff.h: -------------------------------------------------------------------------------- 1 | /* Generated by pilot_coeff_file() Octave function */ 2 | 3 | // const removed since this provides gain 4 | // on the STM32F4 platform 5 | 6 | #ifdef CORTEX_M4 7 | /* const */ float pilot_coeff[]={ 8 | #else 9 | const float pilot_coeff[]={ 10 | #endif 11 | 0.00223001, 12 | 0.00301037, 13 | 0.00471258, 14 | 0.0075934, 15 | 0.0118145, 16 | 0.0174153, 17 | 0.0242969, 18 | 0.0322204, 19 | 0.0408199, 20 | 0.0496286, 21 | 0.0581172, 22 | 0.0657392, 23 | 0.0719806, 24 | 0.0764066, 25 | 0.0787022, 26 | 0.0787022, 27 | 0.0764066, 28 | 0.0719806, 29 | 0.0657392, 30 | 0.0581172, 31 | 0.0496286, 32 | 0.0408199, 33 | 0.0322204, 34 | 0.0242969, 35 | 0.0174153, 36 | 0.0118145, 37 | 0.0075934, 38 | 0.00471258, 39 | 0.00301037, 40 | 0.00223001 41 | }; 42 | -------------------------------------------------------------------------------- /src/codec2/pilots_coh.h: -------------------------------------------------------------------------------- 1 | /* Generated by write_pilot_file() Octave function */ 2 | 3 | float pilots_coh[][PILOTS_NC]={ 4 | { 1.000000, -1.000000, 1.000000, -1.000000, 1.000000, -1.000000, -1.000000}, 5 | { -1.000000, 1.000000, 1.000000, -1.000000, 1.000000, 1.000000, 1.000000} 6 | }; -------------------------------------------------------------------------------- /src/codec2/postfilter.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: postfilter.c 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 13/09/09 6 | 7 | Postfilter to improve sound quality for speech with high levels of 8 | background noise. Unlike mixed-excitation models requires no bits 9 | to be transmitted to handle background noise. 10 | 11 | \*---------------------------------------------------------------------------*/ 12 | 13 | /* 14 | Copyright (C) 2009 David Rowe 15 | 16 | All rights reserved. 17 | 18 | This program is free software; you can redistribute it and/or modify 19 | it under the terms of the GNU Lesser General Public License version 2.1, as 20 | published by the Free Software Foundation. This program is 21 | distributed in the hope that it will be useful, but WITHOUT ANY 22 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 24 | License for more details. 25 | 26 | You should have received a copy of the GNU Lesser General Public License 27 | along with this program; if not, see . 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "defines.h" 36 | #include "comp.h" 37 | #include "dump.h" 38 | #include "sine.h" 39 | #include "postfilter.h" 40 | 41 | /*---------------------------------------------------------------------------*\ 42 | 43 | DEFINES 44 | 45 | \*---------------------------------------------------------------------------*/ 46 | 47 | #define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ 48 | #define BG_BETA 0.1 /* averaging filter constant */ 49 | #define BG_MARGIN 6.0 /* harmonics this far above BG noise are 50 | randomised. Helped make bg noise less 51 | spikey (impulsive) for mmt1, but speech was 52 | perhaps a little rougher. 53 | */ 54 | 55 | /*---------------------------------------------------------------------------*\ 56 | 57 | postfilter() 58 | 59 | The post filter is designed to help with speech corrupted by 60 | background noise. The zero phase model tends to make speech with 61 | background noise sound "clicky". With high levels of background 62 | noise the low level inter-formant parts of the spectrum will contain 63 | noise rather than speech harmonics, so modelling them as voiced 64 | (i.e. a continuous, non-random phase track) is inaccurate. 65 | 66 | Some codecs (like MBE) have a mixed voicing model that breaks the 67 | spectrum into voiced and unvoiced regions. Several bits/frame 68 | (5-12) are required to transmit the frequency selective voicing 69 | information. Mixed excitation also requires accurate voicing 70 | estimation (parameter estimators always break occasionally under 71 | exceptional conditions). 72 | 73 | In our case we use a post filter approach which requires no 74 | additional bits to be transmitted. The decoder measures the average 75 | level of the background noise during unvoiced frames. If a harmonic 76 | is less than this level it is made unvoiced by randomising it's 77 | phases. 78 | 79 | This idea is rather experimental. Some potential problems that may 80 | happen: 81 | 82 | 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track 83 | up to speech level? This would be a bad thing. 84 | 85 | 2/ If background noise suddenly dissapears from the source speech does 86 | estimate drop quickly? What is noise suddenly re-appears? 87 | 88 | 3/ Background noise with a non-flat sepctrum. Current algorithm just 89 | comsiders scpetrum as a whole, but this could be broken up into 90 | bands, each with their own estimator. 91 | 92 | 4/ Males and females with the same level of background noise. Check 93 | performance the same. Changing Wo affects width of each band, may 94 | affect bg energy estimates. 95 | 96 | 5/ Not sure what happens during long periods of voiced speech 97 | e.g. "sshhhhhhh" 98 | 99 | \*---------------------------------------------------------------------------*/ 100 | 101 | void postfilter( 102 | MODEL *model, 103 | float *bg_est 104 | ) 105 | { 106 | int m, uv; 107 | float e, thresh; 108 | 109 | /* determine average energy across spectrum */ 110 | 111 | e = 1E-12; 112 | for(m=1; m<=model->L; m++) 113 | e += model->A[m]*model->A[m]; 114 | 115 | assert(e > 0.0); 116 | e = 10.0*log10f(e/model->L); 117 | 118 | /* If beneath threhold, update bg estimate. The idea 119 | of the threshold is to prevent updating during high level 120 | speech. */ 121 | 122 | if ((e < BG_THRESH) && !model->voiced) 123 | *bg_est = *bg_est*(1.0 - BG_BETA) + e*BG_BETA; 124 | 125 | /* now mess with phases during voiced frames to make any harmonics 126 | less then our background estimate unvoiced. 127 | */ 128 | 129 | uv = 0; 130 | thresh = powf(10.0, (*bg_est + BG_MARGIN)/20.0); 131 | if (model->voiced) 132 | for(m=1; m<=model->L; m++) 133 | if (model->A[m] < thresh) { 134 | model->phi[m] = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX; 135 | uv++; 136 | } 137 | 138 | #ifdef DUMP 139 | dump_bg(e, *bg_est, 100.0*uv/model->L); 140 | #endif 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/codec2/postfilter.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: postfilter.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 13/09/09 6 | 7 | Postfilter header file. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2009 David Rowe 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __POSTFILTER__ 29 | #define __POSTFILTER__ 30 | 31 | void postfilter(MODEL *model, float *bg_est); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/codec2/quantise.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: quantise.h 4 | AUTHOR......: David Rowe 5 | DATE CREATED: 31/5/92 6 | 7 | Quantisation functions for the sinusoidal coder. 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | All rights reserved. 13 | 14 | This program is free software; you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License version 2.1, as 16 | published by the Free Software Foundation. This program is 17 | distributed in the hope that it will be useful, but WITHOUT ANY 18 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 20 | License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with this program; if not, see . 24 | */ 25 | 26 | #ifndef __QUANTISE__ 27 | #define __QUANTISE__ 28 | 29 | #include "codec2_fft.h" 30 | #include "comp.h" 31 | 32 | #define WO_BITS 7 33 | #define WO_LEVELS (1<. 26 | */ 27 | 28 | #ifndef __SINE__ 29 | #define __SINE__ 30 | 31 | #include "defines.h" 32 | #include "comp.h" 33 | #include "codec2_fft.h" 34 | 35 | C2CONST c2const_create(int Fs); 36 | 37 | void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]); 38 | float hpf(float x, float states[]); 39 | void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]); 40 | void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]); 41 | void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase); 42 | float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], COMP W[]); 43 | void make_synthesis_window(C2CONST *c2const, float Pn[]); 44 | void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift); 45 | 46 | #define CODEC2_RAND_MAX 32767 47 | int codec2_rand(void); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/codec2/ssbfilt_coeff.h: -------------------------------------------------------------------------------- 1 | /* 600 - 2600 Hz FIR filter coeffs */ 2 | /* Generated by make_ssbfilt Octave script */ 3 | 4 | #define SSBFILT_N 100 5 | 6 | float ssbfilt_coeff[]={ 7 | 0.000065, 8 | -0.000030, 9 | 0.000041, 10 | 0.000010, 11 | -0.000128, 12 | -0.000072, 13 | -0.000007, 14 | -0.000095, 15 | -0.000063, 16 | 0.000016, 17 | -0.000000, 18 | 0.000022, 19 | -0.000115, 20 | -0.000233, 21 | -0.000023, 22 | -0.000315, 23 | -0.000725, 24 | 0.000073, 25 | 0.000380, 26 | -0.000345, 27 | 0.000895, 28 | 0.002401, 29 | 0.001241, 30 | 0.001409, 31 | 0.003106, 32 | 0.001236, 33 | -0.001117, 34 | -0.001091, 35 | -0.003184, 36 | -0.005981, 37 | -0.006904, 38 | -0.007920, 39 | -0.005588, 40 | -0.002546, 41 | -0.003476, 42 | 0.005155, 43 | 0.017465, 44 | 0.010772, 45 | 0.013033, 46 | 0.035082, 47 | 0.018466, 48 | -0.010261, 49 | 0.016676, 50 | 0.004890, 51 | -0.076807, 52 | -0.055969, 53 | -0.007360, 54 | -0.155769, 55 | -0.203150, 56 | 0.179458, 57 | 0.475523, 58 | 0.179458, 59 | -0.203150, 60 | -0.155769, 61 | -0.007360, 62 | -0.055969, 63 | -0.076807, 64 | 0.004890, 65 | 0.016676, 66 | -0.010261, 67 | 0.018466, 68 | 0.035082, 69 | 0.013033, 70 | 0.010772, 71 | 0.017465, 72 | 0.005155, 73 | -0.003476, 74 | -0.002546, 75 | -0.005588, 76 | -0.007920, 77 | -0.006904, 78 | -0.005981, 79 | -0.003184, 80 | -0.001091, 81 | -0.001117, 82 | 0.001236, 83 | 0.003106, 84 | 0.001409, 85 | 0.001241, 86 | 0.002401, 87 | 0.000895, 88 | -0.000345, 89 | 0.000380, 90 | 0.000073, 91 | -0.000725, 92 | -0.000315, 93 | -0.000023, 94 | -0.000233, 95 | -0.000115, 96 | 0.000022, 97 | -0.000000, 98 | 0.000016, 99 | -0.000063, 100 | -0.000095, 101 | -0.000007, 102 | -0.000072, 103 | -0.000128, 104 | 0.000010, 105 | 0.000041, 106 | -0.000030 107 | }; -------------------------------------------------------------------------------- /src/codec2/tdma.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | 3 | FILE........: tdma.h 4 | AUTHOR......: Brady O'Brien 5 | DATE CREATED: 18 September 2016 6 | 7 | Skeletion of the API for the TDMA FSK modem 8 | 9 | \*---------------------------------------------------------------------------*/ 10 | 11 | /* 12 | Copyright (C) 2016 Brady O'Brien 13 | 14 | All rights reserved. 15 | 16 | This program is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public License version 2.1, as 18 | published by the Free Software Foundation. This program is 19 | distributed in the hope that it will be useful, but WITHOUT ANY 20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program; if not, see . 26 | */ 27 | 28 | #ifndef __CODEC_2_TDMA_H 29 | #define __CODEC_2_TDMA_H 30 | 31 | #include "fsk.h" 32 | #include "freedv_vhf_framing.h" 33 | 34 | //typedef void (*tdma_cb_rx_frame)() 35 | 36 | /* The state for an individual slot */ 37 | enum slot_state { 38 | rx_no_sync, /* Not synched */ 39 | rx_sync, /* Sunk */ 40 | tx_client, /* TX but timed from a different master */ 41 | tx_master /* TX in master mode */ 42 | }; 43 | 44 | /* The state of the entire TDMA modem */ 45 | enum tdma_state { 46 | no_sync, /* No sync */ 47 | pilot_sync, /* Pilot modem has gotten sync, but slots haven't*/ 48 | slot_sync, /* One or more slots are sunk */ 49 | master_sync, /* This modem is the TDMA master */ 50 | }; 51 | 52 | /* TDMA frame type */ 53 | enum tdma_frame_type{ 54 | frame_master, 55 | frame_client, 56 | }; 57 | 58 | /* TDMA frame struct */ 59 | struct TDMA_FRAME { 60 | enum tdma_frame_type type; /* Type of frame */ 61 | int slot_idx; /* Index of slot from where frame was rx-ed */ 62 | uint8_t frame_payload[]; /* Frame payload. TODO: figure out how to sling payloads around */ 63 | }; 64 | 65 | /* TDMA slot struct */ 66 | 67 | struct TDMA_SLOT { 68 | struct FSK * fsk; /* The FSK modem for this slot */ 69 | enum slot_state state; /* Current local slot state */ 70 | int slot_local_frame_offset; /* Where the RX frame starts, in samples, from the perspective of the modem */ 71 | struct TDMA_SLOT * next_slot; /* Next slot in a linked list of slots */ 72 | 73 | }; 74 | 75 | /* TDMA modem */ 76 | struct TDMA_MODEM { 77 | struct FSK * fsk_pilot; /* Pilot modem */ 78 | enum tdma_state state; /* Current state of modem */ 79 | struct TDMA_SLOT * slots; /* Linked list of slot structs */ 80 | 81 | int total_slot_count; 82 | 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/codec2/test.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/codec2/test_bits.h: -------------------------------------------------------------------------------- 1 | /* Generated by test_bits_file() Octave function */ 2 | 3 | const int test_bits[]={ 4 | 0, 5 | 1, 6 | 1, 7 | 0, 8 | 0, 9 | 0, 10 | 1, 11 | 1, 12 | 0, 13 | 0, 14 | 1, 15 | 0, 16 | 1, 17 | 0, 18 | 0, 19 | 1, 20 | 0, 21 | 1, 22 | 1, 23 | 0, 24 | 0, 25 | 1, 26 | 1, 27 | 0, 28 | 0, 29 | 0, 30 | 0, 31 | 0, 32 | 0, 33 | 0, 34 | 0, 35 | 0, 36 | 0, 37 | 0, 38 | 0, 39 | 0, 40 | 1, 41 | 1, 42 | 1, 43 | 0, 44 | 1, 45 | 1, 46 | 0, 47 | 0, 48 | 1, 49 | 1, 50 | 1, 51 | 0, 52 | 1, 53 | 1, 54 | 0, 55 | 1, 56 | 1, 57 | 1, 58 | 1, 59 | 1, 60 | 0, 61 | 0, 62 | 1, 63 | 0, 64 | 0, 65 | 1, 66 | 1, 67 | 1, 68 | 0, 69 | 0, 70 | 1, 71 | 1, 72 | 1, 73 | 0, 74 | 0, 75 | 0, 76 | 0, 77 | 1, 78 | 1, 79 | 1, 80 | 0, 81 | 0, 82 | 1, 83 | 1, 84 | 1, 85 | 1, 86 | 1, 87 | 0, 88 | 1, 89 | 1, 90 | 1, 91 | 0, 92 | 0, 93 | 1, 94 | 1, 95 | 0, 96 | 1, 97 | 1, 98 | 1, 99 | 1, 100 | 1, 101 | 1, 102 | 1, 103 | 0, 104 | 0, 105 | 1, 106 | 1, 107 | 0, 108 | 1, 109 | 0, 110 | 0, 111 | 0, 112 | 1, 113 | 1, 114 | 1, 115 | 0, 116 | 0, 117 | 0, 118 | 0, 119 | 1, 120 | 1, 121 | 1, 122 | 1, 123 | 1, 124 | 0, 125 | 1, 126 | 1, 127 | 0, 128 | 0, 129 | 0, 130 | 1, 131 | 0, 132 | 0, 133 | 1, 134 | 0, 135 | 0, 136 | 0, 137 | 1, 138 | 0, 139 | 0, 140 | 1, 141 | 0, 142 | 0, 143 | 0, 144 | 0, 145 | 0, 146 | 0, 147 | 0, 148 | 0, 149 | 1, 150 | 1, 151 | 0, 152 | 1, 153 | 1, 154 | 0, 155 | 0, 156 | 0, 157 | 1, 158 | 0, 159 | 1, 160 | 1, 161 | 1, 162 | 0, 163 | 1 164 | }; 165 | -------------------------------------------------------------------------------- /src/codec2/test_bits_coh.h: -------------------------------------------------------------------------------- 1 | /* Generated by test_bits_coh_file() Octave function */ 2 | 3 | const int test_bits_coh[]={ 4 | 0, 5 | 1, 6 | 1, 7 | 0, 8 | 0, 9 | 0, 10 | 1, 11 | 1, 12 | 0, 13 | 0, 14 | 1, 15 | 0, 16 | 1, 17 | 0, 18 | 0, 19 | 1, 20 | 0, 21 | 1, 22 | 1, 23 | 0, 24 | 0, 25 | 1, 26 | 1, 27 | 0, 28 | 0, 29 | 0, 30 | 0, 31 | 0, 32 | 0, 33 | 0, 34 | 0, 35 | 0, 36 | 0, 37 | 0, 38 | 0, 39 | 0, 40 | 1, 41 | 1, 42 | 1, 43 | 0, 44 | 1, 45 | 1, 46 | 0, 47 | 0, 48 | 1, 49 | 1, 50 | 1, 51 | 0, 52 | 1, 53 | 1, 54 | 0, 55 | 1, 56 | 1, 57 | 1, 58 | 1, 59 | 1, 60 | 0, 61 | 0, 62 | 1, 63 | 0, 64 | 0, 65 | 1, 66 | 1, 67 | 1, 68 | 0, 69 | 0, 70 | 1, 71 | 1, 72 | 1, 73 | 0, 74 | 0, 75 | 0, 76 | 0, 77 | 1, 78 | 1, 79 | 1, 80 | 0, 81 | 0, 82 | 1, 83 | 1, 84 | 1, 85 | 1, 86 | 1, 87 | 0, 88 | 1, 89 | 1, 90 | 1, 91 | 0, 92 | 0, 93 | 1, 94 | 1, 95 | 0, 96 | 1, 97 | 1, 98 | 1, 99 | 1, 100 | 1, 101 | 1, 102 | 1, 103 | 0, 104 | 0, 105 | 1, 106 | 1, 107 | 0, 108 | 1, 109 | 0, 110 | 0, 111 | 0, 112 | 1, 113 | 1, 114 | 1, 115 | 0, 116 | 0, 117 | 0, 118 | 0, 119 | 1, 120 | 1, 121 | 1, 122 | 1, 123 | 1, 124 | 0, 125 | 1, 126 | 1, 127 | 0, 128 | 0, 129 | 0, 130 | 1, 131 | 0, 132 | 0, 133 | 1, 134 | 0, 135 | 0, 136 | 0, 137 | 1, 138 | 0, 139 | 0, 140 | 1, 141 | 0, 142 | 0, 143 | 0, 144 | 0, 145 | 0, 146 | 0, 147 | 0, 148 | 0, 149 | 1, 150 | 1, 151 | 0, 152 | 1, 153 | 1, 154 | 0, 155 | 0, 156 | 0, 157 | 1, 158 | 0, 159 | 1, 160 | 1, 161 | 1, 162 | 0, 163 | 1, 164 | 1, 165 | 1, 166 | 0, 167 | 1, 168 | 0, 169 | 1, 170 | 0, 171 | 1, 172 | 0, 173 | 0, 174 | 1, 175 | 1, 176 | 0, 177 | 1, 178 | 0, 179 | 1, 180 | 1, 181 | 0, 182 | 0, 183 | 0, 184 | 1, 185 | 0, 186 | 1, 187 | 1, 188 | 1, 189 | 0, 190 | 1, 191 | 1, 192 | 1, 193 | 1, 194 | 0, 195 | 0, 196 | 0, 197 | 1, 198 | 0, 199 | 0, 200 | 0, 201 | 1, 202 | 0, 203 | 0, 204 | 0, 205 | 1, 206 | 1, 207 | 0, 208 | 0, 209 | 0, 210 | 1, 211 | 1, 212 | 0, 213 | 0, 214 | 1, 215 | 1, 216 | 1, 217 | 0, 218 | 1, 219 | 1, 220 | 0, 221 | 1, 222 | 0, 223 | 1, 224 | 0, 225 | 0, 226 | 1, 227 | 0, 228 | 1, 229 | 1, 230 | 1, 231 | 0, 232 | 0, 233 | 0, 234 | 1, 235 | 1, 236 | 1, 237 | 1, 238 | 0, 239 | 1, 240 | 0, 241 | 0, 242 | 0, 243 | 1, 244 | 1, 245 | 1, 246 | 0, 247 | 1, 248 | 1, 249 | 0, 250 | 1, 251 | 0, 252 | 0, 253 | 0, 254 | 1, 255 | 1, 256 | 1, 257 | 0, 258 | 0, 259 | 1, 260 | 1, 261 | 0, 262 | 1, 263 | 0, 264 | 0, 265 | 1, 266 | 0, 267 | 0, 268 | 1, 269 | 0, 270 | 0, 271 | 0, 272 | 0, 273 | 1, 274 | 0, 275 | 1, 276 | 0, 277 | 1, 278 | 1, 279 | 0, 280 | 0, 281 | 0, 282 | 0, 283 | 1, 284 | 0, 285 | 0, 286 | 1, 287 | 0, 288 | 1, 289 | 0, 290 | 0, 291 | 0, 292 | 1, 293 | 1, 294 | 1, 295 | 0, 296 | 0, 297 | 1, 298 | 1, 299 | 1, 300 | 1, 301 | 1, 302 | 0, 303 | 1, 304 | 0, 305 | 0, 306 | 0, 307 | 0, 308 | 1, 309 | 0, 310 | 1, 311 | 1, 312 | 1, 313 | 0, 314 | 0, 315 | 0, 316 | 0, 317 | 1, 318 | 1, 319 | 0, 320 | 0, 321 | 1, 322 | 1, 323 | 1, 324 | 0, 325 | 0, 326 | 0, 327 | 0, 328 | 1, 329 | 0, 330 | 0, 331 | 1, 332 | 0, 333 | 1, 334 | 0, 335 | 1, 336 | 0, 337 | 1, 338 | 1, 339 | 0, 340 | 1, 341 | 0, 342 | 1, 343 | 1, 344 | 1, 345 | 0, 346 | 0, 347 | 1, 348 | 1, 349 | 0, 350 | 1, 351 | 0, 352 | 1, 353 | 0, 354 | 0, 355 | 1, 356 | 1, 357 | 1, 358 | 1, 359 | 1, 360 | 1, 361 | 0, 362 | 0, 363 | 0, 364 | 1, 365 | 1, 366 | 0, 367 | 0, 368 | 1, 369 | 1, 370 | 1, 371 | 1, 372 | 1, 373 | 0, 374 | 0, 375 | 0, 376 | 0, 377 | 0, 378 | 1, 379 | 0, 380 | 1, 381 | 0, 382 | 0, 383 | 0, 384 | 0, 385 | 0, 386 | 1, 387 | 0, 388 | 0, 389 | 1, 390 | 0, 391 | 0, 392 | 1, 393 | 1, 394 | 1, 395 | 0, 396 | 1, 397 | 1, 398 | 0, 399 | 0, 400 | 0, 401 | 0, 402 | 0, 403 | 1, 404 | 1, 405 | 1, 406 | 0, 407 | 1, 408 | 0, 409 | 0, 410 | 1, 411 | 1, 412 | 0, 413 | 1, 414 | 1, 415 | 0, 416 | 1, 417 | 1, 418 | 0, 419 | 1, 420 | 1, 421 | 1, 422 | 1, 423 | 1, 424 | 1, 425 | 1, 426 | 0, 427 | 0, 428 | 0, 429 | 1, 430 | 1, 431 | 0, 432 | 1, 433 | 1, 434 | 0, 435 | 1, 436 | 0, 437 | 1, 438 | 0, 439 | 1, 440 | 1, 441 | 1, 442 | 0, 443 | 1, 444 | 1, 445 | 0, 446 | 1, 447 | 1, 448 | 1, 449 | 1, 450 | 0, 451 | 1, 452 | 1, 453 | 0, 454 | 1, 455 | 0, 456 | 0, 457 | 0, 458 | 0, 459 | 1, 460 | 1, 461 | 0, 462 | 1, 463 | 0, 464 | 0, 465 | 0, 466 | 0, 467 | 1, 468 | 0, 469 | 0, 470 | 0, 471 | 0, 472 | 1, 473 | 1, 474 | 1, 475 | 0, 476 | 0, 477 | 1, 478 | 0, 479 | 1, 480 | 0, 481 | 1, 482 | 1, 483 | 1, 484 | 1, 485 | 1, 486 | 0, 487 | 1, 488 | 1, 489 | 1, 490 | 0, 491 | 0, 492 | 0, 493 | 1, 494 | 0, 495 | 1, 496 | 1, 497 | 1, 498 | 1, 499 | 1, 500 | 0, 501 | 1, 502 | 1, 503 | 0, 504 | 1, 505 | 0, 506 | 1, 507 | 0, 508 | 0, 509 | 0, 510 | 0, 511 | 0, 512 | 1, 513 | 1, 514 | 0, 515 | 1, 516 | 0, 517 | 0, 518 | 0, 519 | 0, 520 | 1, 521 | 1, 522 | 1, 523 | 1, 524 | 1, 525 | 0, 526 | 1, 527 | 0, 528 | 1, 529 | 1, 530 | 0, 531 | 0, 532 | 1, 533 | 1, 534 | 0, 535 | 0, 536 | 0, 537 | 0, 538 | 0, 539 | 1, 540 | 1, 541 | 1, 542 | 1, 543 | 1, 544 | 0, 545 | 1, 546 | 1, 547 | 1, 548 | 1, 549 | 0, 550 | 1, 551 | 1, 552 | 1, 553 | 1, 554 | 1, 555 | 1, 556 | 1, 557 | 1, 558 | 0, 559 | 0, 560 | 1, 561 | 1, 562 | 1, 563 | 0 564 | }; 565 | -------------------------------------------------------------------------------- /src/codec2/test_bits_ofdm.h: -------------------------------------------------------------------------------- 1 | /* Generated by test_bits_ofdm_file() Octave function */ 2 | 3 | const int test_bits_ofdm[]={ 4 | 1, 5 | 1, 6 | 0, 7 | 0, 8 | 1, 9 | 1, 10 | 1, 11 | 0, 12 | 1, 13 | 0, 14 | 1, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | 0, 20 | 0, 21 | 0, 22 | 0, 23 | 1, 24 | 1, 25 | 0, 26 | 1, 27 | 0, 28 | 1, 29 | 0, 30 | 0, 31 | 0, 32 | 0, 33 | 0, 34 | 0, 35 | 0, 36 | 0, 37 | 0, 38 | 0, 39 | 1, 40 | 0, 41 | 0, 42 | 0, 43 | 0, 44 | 0, 45 | 1, 46 | 1, 47 | 1, 48 | 1, 49 | 1, 50 | 1, 51 | 0, 52 | 1, 53 | 0, 54 | 1, 55 | 0, 56 | 1, 57 | 1, 58 | 0, 59 | 1, 60 | 0, 61 | 0, 62 | 0, 63 | 0, 64 | 1, 65 | 0, 66 | 1, 67 | 0, 68 | 1, 69 | 0, 70 | 1, 71 | 1, 72 | 1, 73 | 0, 74 | 1, 75 | 0, 76 | 1, 77 | 0, 78 | 1, 79 | 1, 80 | 0, 81 | 1, 82 | 1, 83 | 0, 84 | 1, 85 | 0, 86 | 0, 87 | 1, 88 | 0, 89 | 1, 90 | 0, 91 | 0, 92 | 0, 93 | 1, 94 | 1, 95 | 1, 96 | 0, 97 | 0, 98 | 0, 99 | 0, 100 | 0, 101 | 0, 102 | 0, 103 | 0, 104 | 1, 105 | 0, 106 | 0, 107 | 1, 108 | 1, 109 | 1, 110 | 0, 111 | 0, 112 | 1, 113 | 1, 114 | 1, 115 | 0, 116 | 0, 117 | 1, 118 | 1, 119 | 1, 120 | 0, 121 | 1, 122 | 1, 123 | 1, 124 | 1, 125 | 1, 126 | 1, 127 | 1, 128 | 1, 129 | 0, 130 | 1, 131 | 1, 132 | 1, 133 | 0, 134 | 0, 135 | 1, 136 | 1, 137 | 0, 138 | 0, 139 | 1, 140 | 0, 141 | 0, 142 | 0, 143 | 0, 144 | 0, 145 | 0, 146 | 0, 147 | 1, 148 | 0, 149 | 0, 150 | 1, 151 | 1, 152 | 1, 153 | 1, 154 | 0, 155 | 1, 156 | 0, 157 | 1, 158 | 1, 159 | 0, 160 | 1, 161 | 1, 162 | 1, 163 | 1, 164 | 0, 165 | 1, 166 | 1, 167 | 1, 168 | 1, 169 | 1, 170 | 0, 171 | 0, 172 | 1, 173 | 1, 174 | 1, 175 | 0, 176 | 1, 177 | 0, 178 | 1, 179 | 0, 180 | 1, 181 | 1, 182 | 1, 183 | 1, 184 | 1, 185 | 1, 186 | 1, 187 | 0, 188 | 0, 189 | 1, 190 | 1, 191 | 1, 192 | 1, 193 | 0, 194 | 0, 195 | 0, 196 | 1, 197 | 1, 198 | 1, 199 | 1, 200 | 1, 201 | 1, 202 | 1, 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 1, 208 | 1, 209 | 0, 210 | 0, 211 | 0, 212 | 1, 213 | 1, 214 | 1, 215 | 0, 216 | 1, 217 | 0, 218 | 0, 219 | 1, 220 | 1, 221 | 0, 222 | 1, 223 | 1, 224 | 0, 225 | 0, 226 | 0, 227 | 1 228 | }; 229 | 230 | -------------------------------------------------------------------------------- /src/codec2/varicode.h: -------------------------------------------------------------------------------- 1 | //========================================================================== 2 | // Name: varicode.h 3 | // Purpose: Varicode encoded and decode functions 4 | // Created: Nov 24, 2012 5 | // Authors: David Rowe 6 | // 7 | // License: 8 | // 9 | // This program is free software; you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License version 2.1, 11 | // as published by the Free Software Foundation. This program is 12 | // distributed in the hope that it will be useful, but WITHOUT ANY 13 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 | // License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program; if not, see . 19 | // 20 | //========================================================================== 21 | 22 | #ifndef __VARICODE__ 23 | #define __VARICODE__ 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | 28 | #endif 29 | 30 | #define VARICODE_MAX_BITS (10+2) /* max varicode bits for each ascii character */ 31 | /* 10 bits for code plus 2 0 bits for inter-character space */ 32 | 33 | struct VARICODE_DEC { 34 | int state; 35 | int n_zeros; 36 | int v_len; 37 | unsigned short packed; 38 | int code_num; 39 | int n_in; 40 | int in[2]; 41 | }; 42 | 43 | int varicode_encode(short varicode_out[], char ascii_in[], int max_out, int n_in, int code_num); 44 | void varicode_decode_init(struct VARICODE_DEC *dec_states, int code_num); 45 | int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in); 46 | void varicode_set_code_num(struct VARICODE_DEC *dec_states, int code_num); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/libsamplerate/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016, Erik de Castro Lopo 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 16 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 18 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /src/libsamplerate/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2002-2016, Erik de Castro Lopo 3 | ** All rights reserved. 4 | ** 5 | ** This code is released under 2-clause BSD license. Please see the 6 | ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING 7 | */ 8 | 9 | #ifndef COMMON_H_INCLUDED 10 | #define COMMON_H_INCLUDED 11 | 12 | #ifdef HAVE_STDINT_H 13 | #include 14 | #elif (SIZEOF_INT == 4) 15 | typedef int int32_t ; 16 | #elif (SIZEOF_LONG == 4) 17 | typedef long int32_t ; 18 | #endif 19 | 20 | #define SRC_MAX_RATIO 256 21 | #define SRC_MAX_RATIO_STR "256" 22 | 23 | #define SRC_MIN_RATIO_DIFF (1e-20) 24 | 25 | #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 26 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 27 | 28 | #define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0]))) 29 | #define OFFSETOF(type,member) ((int) (&((type*) 0)->member)) 30 | 31 | #define MAKE_MAGIC(a,b,c,d,e,f) ((a) + ((b) << 4) + ((c) << 8) + ((d) << 12) + ((e) << 16) + ((f) << 20)) 32 | 33 | /* 34 | ** Inspiration : http://sourcefrog.net/weblog/software/languages/C/unused.html 35 | */ 36 | #ifdef UNUSED 37 | #elif defined (__GNUC__) 38 | # define UNUSED(x) UNUSED_ ## x __attribute__ ((unused)) 39 | #elif defined (__LCLINT__) 40 | # define UNUSED(x) /*@unused@*/ x 41 | #else 42 | # define UNUSED(x) x 43 | #endif 44 | 45 | #ifdef __GNUC__ 46 | # define WARN_UNUSED __attribute__ ((warn_unused_result)) 47 | #else 48 | # define WARN_UNUSED 49 | #endif 50 | 51 | 52 | #include "samplerate.h" 53 | 54 | enum 55 | { SRC_FALSE = 0, 56 | SRC_TRUE = 1, 57 | 58 | SRC_MODE_PROCESS = 555, 59 | SRC_MODE_CALLBACK = 556 60 | } ; 61 | 62 | enum 63 | { SRC_ERR_NO_ERROR = 0, 64 | 65 | SRC_ERR_MALLOC_FAILED, 66 | SRC_ERR_BAD_STATE, 67 | SRC_ERR_BAD_DATA, 68 | SRC_ERR_BAD_DATA_PTR, 69 | SRC_ERR_NO_PRIVATE, 70 | SRC_ERR_BAD_SRC_RATIO, 71 | SRC_ERR_BAD_PROC_PTR, 72 | SRC_ERR_SHIFT_BITS, 73 | SRC_ERR_FILTER_LEN, 74 | SRC_ERR_BAD_CONVERTER, 75 | SRC_ERR_BAD_CHANNEL_COUNT, 76 | SRC_ERR_SINC_BAD_BUFFER_LEN, 77 | SRC_ERR_SIZE_INCOMPATIBILITY, 78 | SRC_ERR_BAD_PRIV_PTR, 79 | SRC_ERR_BAD_SINC_STATE, 80 | SRC_ERR_DATA_OVERLAP, 81 | SRC_ERR_BAD_CALLBACK, 82 | SRC_ERR_BAD_MODE, 83 | SRC_ERR_NULL_CALLBACK, 84 | SRC_ERR_NO_VARIABLE_RATIO, 85 | SRC_ERR_SINC_PREPARE_DATA_BAD_LEN, 86 | SRC_ERR_BAD_INTERNAL_STATE, 87 | 88 | /* This must be the last error number. */ 89 | SRC_ERR_MAX_ERROR 90 | } ; 91 | 92 | typedef struct SRC_PRIVATE_tag 93 | { double last_ratio, last_position ; 94 | 95 | int error ; 96 | int channels ; 97 | 98 | /* SRC_MODE_PROCESS or SRC_MODE_CALLBACK */ 99 | int mode ; 100 | 101 | /* Pointer to data to converter specific data. */ 102 | void *private_data ; 103 | 104 | /* Varispeed process function. */ 105 | int (*vari_process) (struct SRC_PRIVATE_tag *psrc, SRC_DATA *data) ; 106 | 107 | /* Constant speed process function. */ 108 | int (*const_process) (struct SRC_PRIVATE_tag *psrc, SRC_DATA *data) ; 109 | 110 | /* State reset. */ 111 | void (*reset) (struct SRC_PRIVATE_tag *psrc) ; 112 | 113 | /* Data specific to SRC_MODE_CALLBACK. */ 114 | src_callback_t callback_func ; 115 | void *user_callback_data ; 116 | long saved_frames ; 117 | const float *saved_data ; 118 | } SRC_PRIVATE ; 119 | 120 | /* In src_sinc.c */ 121 | const char* sinc_get_name (int src_enum) ; 122 | const char* sinc_get_description (int src_enum) ; 123 | 124 | int sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) ; 125 | 126 | /* In src_linear.c */ 127 | const char* linear_get_name (int src_enum) ; 128 | const char* linear_get_description (int src_enum) ; 129 | 130 | int linear_set_converter (SRC_PRIVATE *psrc, int src_enum) ; 131 | 132 | /* In src_zoh.c */ 133 | const char* zoh_get_name (int src_enum) ; 134 | const char* zoh_get_description (int src_enum) ; 135 | 136 | int zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) ; 137 | 138 | /*---------------------------------------------------------- 139 | ** Common static inline functions. 140 | */ 141 | 142 | static inline double 143 | fmod_one (double x) 144 | { double res ; 145 | 146 | res = x - lrint (x) ; 147 | if (res < 0.0) 148 | return res + 1.0 ; 149 | 150 | return res ; 151 | } /* fmod_one */ 152 | 153 | static inline int 154 | is_bad_src_ratio (double ratio) 155 | { return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ; 156 | } /* is_bad_src_ratio */ 157 | 158 | 159 | #endif /* COMMON_H_INCLUDED */ 160 | 161 | -------------------------------------------------------------------------------- /src/libsamplerate/config.h: -------------------------------------------------------------------------------- 1 | /* src/config.h. Generated from config.h.in by configure. */ 2 | /* src/config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Set to 1 if the compile is GNU GCC. */ 5 | #define COMPILER_IS_GCC 1 6 | 7 | /* Target processor clips on negative float to int conversion. */ 8 | #define CPU_CLIPS_NEGATIVE 0 9 | 10 | /* Target processor clips on positive float to int conversion. */ 11 | #define CPU_CLIPS_POSITIVE 0 12 | 13 | /* Target processor is big endian. */ 14 | #define CPU_IS_BIG_ENDIAN 0 15 | 16 | /* Target processor is little endian. */ 17 | #define CPU_IS_LITTLE_ENDIAN 1 18 | 19 | /* Major version of GCC or 3 otherwise. */ 20 | #define GCC_MAJOR_VERSION 4 21 | 22 | /* Define to 1 if you have the `alarm' function. */ 23 | #define HAVE_ALARM 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | /* #undef HAVE_ALSA_ASOUNDLIB_H */ 27 | 28 | /* Define to 1 if you have the `calloc' function. */ 29 | #define HAVE_CALLOC 1 30 | 31 | /* Define to 1 if you have the `ceil' function. */ 32 | #define HAVE_CEIL 1 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #define HAVE_DLFCN_H 1 36 | 37 | /* Set to 1 if you have libfftw3. */ 38 | /* #undef HAVE_FFTW3 */ 39 | 40 | /* Define to 1 if you have the `floor' function. */ 41 | #define HAVE_FLOOR 1 42 | 43 | /* Define to 1 if you have the `fmod' function. */ 44 | #define HAVE_FMOD 1 45 | 46 | /* Define to 1 if you have the `free' function. */ 47 | #define HAVE_FREE 1 48 | 49 | /* Define to 1 if you have the header file. */ 50 | #define HAVE_INTTYPES_H 1 51 | 52 | /* Define to 1 if you have the `m' library (-lm). */ 53 | #define HAVE_LIBM 1 54 | 55 | /* Define if you have C99's lrint function. */ 56 | #define HAVE_LRINT 1 57 | 58 | /* Define if you have C99's lrintf function. */ 59 | #define HAVE_LRINTF 1 60 | 61 | /* Define to 1 if you have the `malloc' function. */ 62 | #define HAVE_MALLOC 1 63 | 64 | /* Define to 1 if you have the `memcpy' function. */ 65 | #define HAVE_MEMCPY 1 66 | 67 | /* Define to 1 if you have the `memmove' function. */ 68 | #define HAVE_MEMMOVE 1 69 | 70 | /* Define to 1 if you have the header file. */ 71 | #define HAVE_MEMORY_H 1 72 | 73 | /* Define if you have signal SIGALRM. */ 74 | #define HAVE_SIGALRM 1 75 | 76 | /* Define to 1 if you have the `signal' function. */ 77 | #define HAVE_SIGNAL 1 78 | 79 | /* Set to 1 if you have libsndfile. */ 80 | #define HAVE_SNDFILE 0 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #define HAVE_STDINT_H 1 84 | 85 | /* Define to 1 if you have the header file. */ 86 | #define HAVE_STDLIB_H 1 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #define HAVE_STRINGS_H 1 90 | 91 | /* Define to 1 if you have the header file. */ 92 | #define HAVE_STRING_H 1 93 | 94 | /* Define to 1 if you have the header file. */ 95 | #define HAVE_SYS_STAT_H 1 96 | 97 | /* Define to 1 if you have the header file. */ 98 | #define HAVE_SYS_TIMES_H 1 99 | 100 | /* Define to 1 if you have the header file. */ 101 | #define HAVE_SYS_TYPES_H 1 102 | 103 | /* Define to 1 if you have the header file. */ 104 | #define HAVE_UNISTD_H 1 105 | 106 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 107 | #define LT_OBJDIR ".libs/" 108 | 109 | /* Set to 1 if compiling for Win32 */ 110 | #define OS_IS_WIN32 0 111 | 112 | /* Name of package */ 113 | #define PACKAGE "libsamplerate" 114 | 115 | /* Define to the address where bug reports for this package should be sent. */ 116 | #define PACKAGE_BUGREPORT "erikd@mega-nerd.com" 117 | 118 | /* Define to the full name of this package. */ 119 | #define PACKAGE_NAME "libsamplerate" 120 | 121 | /* Define to the full name and version of this package. */ 122 | #define PACKAGE_STRING "libsamplerate 0.1.9" 123 | 124 | /* Define to the one symbol short name of this package. */ 125 | #define PACKAGE_TARNAME "libsamplerate" 126 | 127 | /* Define to the home page for this package. */ 128 | #define PACKAGE_URL "http://www.mega-nerd.com/libsamplerate/" 129 | 130 | /* Define to the version of this package. */ 131 | #define PACKAGE_VERSION "0.1.9" 132 | 133 | /* The size of `double', as computed by sizeof. */ 134 | #define SIZEOF_DOUBLE 8 135 | 136 | /* The size of `float', as computed by sizeof. */ 137 | #define SIZEOF_FLOAT 4 138 | 139 | /* The size of `int', as computed by sizeof. */ 140 | #define SIZEOF_INT 4 141 | 142 | /* The size of `long', as computed by sizeof. */ 143 | #define SIZEOF_LONG 8 144 | 145 | /* Define to 1 if you have the ANSI C header files. */ 146 | #define STDC_HEADERS 1 147 | 148 | /* Version number of package */ 149 | #define VERSION "0.1.9" 150 | -------------------------------------------------------------------------------- /src/libsamplerate/samplerate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2002-2016, Erik de Castro Lopo 3 | ** All rights reserved. 4 | ** 5 | ** This code is released under 2-clause BSD license. Please see the 6 | ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING 7 | */ 8 | 9 | /* 10 | ** API documentation is available here: 11 | ** http://www.mega-nerd.com/SRC/api.html 12 | */ 13 | 14 | #ifndef SAMPLERATE_H 15 | #define SAMPLERATE_H 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif /* __cplusplus */ 20 | 21 | 22 | /* Opaque data type SRC_STATE. */ 23 | typedef struct SRC_STATE_tag SRC_STATE ; 24 | 25 | /* SRC_DATA is used to pass data to src_simple() and src_process(). */ 26 | typedef struct 27 | { const float *data_in ; 28 | float *data_out ; 29 | 30 | long input_frames, output_frames ; 31 | long input_frames_used, output_frames_gen ; 32 | 33 | int end_of_input ; 34 | 35 | double src_ratio ; 36 | } SRC_DATA ; 37 | 38 | /* 39 | ** User supplied callback function type for use with src_callback_new() 40 | ** and src_callback_read(). First parameter is the same pointer that was 41 | ** passed into src_callback_new(). Second parameter is pointer to a 42 | ** pointer. The user supplied callback function must modify *data to 43 | ** point to the start of the user supplied float array. The user supplied 44 | ** function must return the number of frames that **data points to. 45 | */ 46 | 47 | typedef long (*src_callback_t) (void *cb_data, float **data) ; 48 | 49 | /* 50 | ** Standard initialisation function : return an anonymous pointer to the 51 | ** internal state of the converter. Choose a converter from the enums below. 52 | ** Error returned in *error. 53 | */ 54 | 55 | SRC_STATE* src_new (int converter_type, int channels, int *error) ; 56 | 57 | /* 58 | ** Initilisation for callback based API : return an anonymous pointer to the 59 | ** internal state of the converter. Choose a converter from the enums below. 60 | ** The cb_data pointer can point to any data or be set to NULL. Whatever the 61 | ** value, when processing, user supplied function "func" gets called with 62 | ** cb_data as first parameter. 63 | */ 64 | 65 | SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels, 66 | int *error, void* cb_data) ; 67 | 68 | /* 69 | ** Cleanup all internal allocations. 70 | ** Always returns NULL. 71 | */ 72 | 73 | SRC_STATE* src_delete (SRC_STATE *state) ; 74 | 75 | /* 76 | ** Standard processing function. 77 | ** Returns non zero on error. 78 | */ 79 | 80 | int src_process (SRC_STATE *state, SRC_DATA *data) ; 81 | 82 | /* 83 | ** Callback based processing function. Read up to frames worth of data from 84 | ** the converter int *data and return frames read or -1 on error. 85 | */ 86 | long src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data) ; 87 | 88 | /* 89 | ** Simple interface for performing a single conversion from input buffer to 90 | ** output buffer at a fixed conversion ratio. 91 | ** Simple interface does not require initialisation as it can only operate on 92 | ** a single buffer worth of audio. 93 | */ 94 | 95 | int src_simple (SRC_DATA *data, int converter_type, int channels) ; 96 | 97 | /* 98 | ** This library contains a number of different sample rate converters, 99 | ** numbered 0 through N. 100 | ** 101 | ** Return a string giving either a name or a more full description of each 102 | ** sample rate converter or NULL if no sample rate converter exists for 103 | ** the given value. The converters are sequentially numbered from 0 to N. 104 | */ 105 | 106 | const char *src_get_name (int converter_type) ; 107 | const char *src_get_description (int converter_type) ; 108 | const char *src_get_version (void) ; 109 | 110 | /* 111 | ** Set a new SRC ratio. This allows step responses 112 | ** in the conversion ratio. 113 | ** Returns non zero on error. 114 | */ 115 | 116 | int src_set_ratio (SRC_STATE *state, double new_ratio) ; 117 | 118 | /* 119 | ** Get the current channel count. 120 | ** Returns negative on error, positive channel count otherwise 121 | */ 122 | 123 | int src_get_channels (SRC_STATE *state) ; 124 | 125 | /* 126 | ** Reset the internal SRC state. 127 | ** Does not modify the quality settings. 128 | ** Does not free any memory allocations. 129 | ** Returns non zero on error. 130 | */ 131 | 132 | int src_reset (SRC_STATE *state) ; 133 | 134 | /* 135 | ** Return TRUE if ratio is a valid conversion ratio, FALSE 136 | ** otherwise. 137 | */ 138 | 139 | int src_is_valid_ratio (double ratio) ; 140 | 141 | /* 142 | ** Return an error number. 143 | */ 144 | 145 | int src_error (SRC_STATE *state) ; 146 | 147 | /* 148 | ** Convert the error number into a string. 149 | */ 150 | const char* src_strerror (int error) ; 151 | 152 | /* 153 | ** The following enums can be used to set the interpolator type 154 | ** using the function src_set_converter(). 155 | */ 156 | 157 | enum 158 | { 159 | SRC_SINC_BEST_QUALITY = 0, 160 | SRC_SINC_MEDIUM_QUALITY = 1, 161 | SRC_SINC_FASTEST = 2, 162 | SRC_ZERO_ORDER_HOLD = 3, 163 | SRC_LINEAR = 4, 164 | } ; 165 | 166 | /* 167 | ** Extra helper functions for converting from short to float and 168 | ** back again. 169 | */ 170 | 171 | void src_short_to_float_array (const short *in, float *out, int len) ; 172 | void src_float_to_short_array (const float *in, short *out, int len) ; 173 | 174 | void src_int_to_float_array (const int *in, float *out, int len) ; 175 | void src_float_to_int_array (const float *in, int *out, int len) ; 176 | 177 | 178 | #ifdef __cplusplus 179 | } /* extern "C" */ 180 | #endif /* __cplusplus */ 181 | 182 | #endif /* SAMPLERATE_H */ 183 | 184 | -------------------------------------------------------------------------------- /src/libsamplerate/src_zoh.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2002-2016, Erik de Castro Lopo 3 | ** All rights reserved. 4 | ** 5 | ** This code is released under 2-clause BSD license. Please see the 6 | ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "config.h" 14 | #include "float_cast.h" 15 | #include "common.h" 16 | 17 | static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; 18 | static void zoh_reset (SRC_PRIVATE *psrc) ; 19 | 20 | /*======================================================================================== 21 | */ 22 | 23 | #define ZOH_MAGIC_MARKER MAKE_MAGIC ('s', 'r', 'c', 'z', 'o', 'h') 24 | 25 | typedef struct 26 | { int zoh_magic_marker ; 27 | int channels ; 28 | int reset ; 29 | long in_count, in_used ; 30 | long out_count, out_gen ; 31 | float last_value [1] ; 32 | } ZOH_DATA ; 33 | 34 | /*---------------------------------------------------------------------------------------- 35 | */ 36 | 37 | static int 38 | zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) 39 | { ZOH_DATA *priv ; 40 | double src_ratio, input_index, rem ; 41 | int ch ; 42 | 43 | if (data->input_frames <= 0) 44 | return SRC_ERR_NO_ERROR ; 45 | 46 | if (psrc->private_data == NULL) 47 | return SRC_ERR_NO_PRIVATE ; 48 | 49 | priv = (ZOH_DATA*) psrc->private_data ; 50 | 51 | if (priv->reset) 52 | { /* If we have just been reset, set the last_value data. */ 53 | for (ch = 0 ; ch < priv->channels ; ch++) 54 | priv->last_value [ch] = data->data_in [ch] ; 55 | priv->reset = 0 ; 56 | } ; 57 | 58 | priv->in_count = data->input_frames * priv->channels ; 59 | priv->out_count = data->output_frames * priv->channels ; 60 | priv->in_used = priv->out_gen = 0 ; 61 | 62 | src_ratio = psrc->last_ratio ; 63 | 64 | if (is_bad_src_ratio (src_ratio)) 65 | return SRC_ERR_BAD_INTERNAL_STATE ; 66 | 67 | input_index = psrc->last_position ; 68 | 69 | /* Calculate samples before first sample in input array. */ 70 | while (input_index < 1.0 && priv->out_gen < priv->out_count) 71 | { 72 | if (priv->in_used + priv->channels * input_index >= priv->in_count) 73 | break ; 74 | 75 | if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) 76 | src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; 77 | 78 | for (ch = 0 ; ch < priv->channels ; ch++) 79 | { data->data_out [priv->out_gen] = priv->last_value [ch] ; 80 | priv->out_gen ++ ; 81 | } ; 82 | 83 | /* Figure out the next index. */ 84 | input_index += 1.0 / src_ratio ; 85 | } ; 86 | 87 | rem = fmod_one (input_index) ; 88 | priv->in_used += priv->channels * lrint (input_index - rem) ; 89 | input_index = rem ; 90 | 91 | /* Main processing loop. */ 92 | while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index <= priv->in_count) 93 | { 94 | if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) 95 | src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; 96 | 97 | for (ch = 0 ; ch < priv->channels ; ch++) 98 | { data->data_out [priv->out_gen] = data->data_in [priv->in_used - priv->channels + ch] ; 99 | priv->out_gen ++ ; 100 | } ; 101 | 102 | /* Figure out the next index. */ 103 | input_index += 1.0 / src_ratio ; 104 | rem = fmod_one (input_index) ; 105 | 106 | priv->in_used += priv->channels * lrint (input_index - rem) ; 107 | input_index = rem ; 108 | } ; 109 | 110 | if (priv->in_used > priv->in_count) 111 | { input_index += (priv->in_used - priv->in_count) / priv->channels ; 112 | priv->in_used = priv->in_count ; 113 | } ; 114 | 115 | psrc->last_position = input_index ; 116 | 117 | if (priv->in_used > 0) 118 | for (ch = 0 ; ch < priv->channels ; ch++) 119 | priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ; 120 | 121 | /* Save current ratio rather then target ratio. */ 122 | psrc->last_ratio = src_ratio ; 123 | 124 | data->input_frames_used = priv->in_used / priv->channels ; 125 | data->output_frames_gen = priv->out_gen / priv->channels ; 126 | 127 | return SRC_ERR_NO_ERROR ; 128 | } /* zoh_vari_process */ 129 | 130 | /*------------------------------------------------------------------------------ 131 | */ 132 | 133 | const char* 134 | zoh_get_name (int src_enum) 135 | { 136 | if (src_enum == SRC_ZERO_ORDER_HOLD) 137 | return "ZOH Interpolator" ; 138 | 139 | return NULL ; 140 | } /* zoh_get_name */ 141 | 142 | const char* 143 | zoh_get_description (int src_enum) 144 | { 145 | if (src_enum == SRC_ZERO_ORDER_HOLD) 146 | return "Zero order hold interpolator, very fast, poor quality." ; 147 | 148 | return NULL ; 149 | } /* zoh_get_descrition */ 150 | 151 | int 152 | zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) 153 | { ZOH_DATA *priv = NULL ; 154 | 155 | if (src_enum != SRC_ZERO_ORDER_HOLD) 156 | return SRC_ERR_BAD_CONVERTER ; 157 | 158 | if (psrc->private_data != NULL) 159 | { free (psrc->private_data) ; 160 | psrc->private_data = NULL ; 161 | } ; 162 | 163 | if (psrc->private_data == NULL) 164 | { priv = calloc (1, sizeof (*priv) + psrc->channels * sizeof (float)) ; 165 | psrc->private_data = priv ; 166 | } ; 167 | 168 | if (priv == NULL) 169 | return SRC_ERR_MALLOC_FAILED ; 170 | 171 | priv->zoh_magic_marker = ZOH_MAGIC_MARKER ; 172 | priv->channels = psrc->channels ; 173 | 174 | psrc->const_process = zoh_vari_process ; 175 | psrc->vari_process = zoh_vari_process ; 176 | psrc->reset = zoh_reset ; 177 | 178 | zoh_reset (psrc) ; 179 | 180 | return SRC_ERR_NO_ERROR ; 181 | } /* zoh_set_converter */ 182 | 183 | /*=================================================================================== 184 | */ 185 | 186 | static void 187 | zoh_reset (SRC_PRIVATE *psrc) 188 | { ZOH_DATA *priv ; 189 | 190 | priv = (ZOH_DATA*) psrc->private_data ; 191 | if (priv == NULL) 192 | return ; 193 | 194 | priv->channels = psrc->channels ; 195 | priv->reset = 1 ; 196 | memset (priv->last_value, 0, sizeof (priv->last_value [0]) * priv->channels) ; 197 | 198 | return ; 199 | } /* zoh_reset */ 200 | 201 | --------------------------------------------------------------------------------