diff --git a/Makefile b/Makefile
index 6b77fed556d45a33c67ce5ef1c7f7c030a4ed7ad..1752fc907c9fb2fb6617c138e1a2fd892e721eaf 100644
--- a/Makefile
+++ b/Makefile
@@ -38,9 +38,10 @@ PARAMS_RASPI = -mfloat-abi=hard -mcpu=arm1176jzf-s -mfpu=vfp -funsafe-math-optim
 PARAMS_ARM = $(if $(call cpufeature,BCM2708,dummy-text),$(PARAMS_RASPI),$(PARAMS_NEON))
 PARAMS_SIMD = $(if $(call cpufeature,sse,dummy-text),$(PARAMS_SSE),$(PARAMS_ARM))
 PARAMS_LOOPVECT = -O3 -ffast-math -fdump-tree-vect-details -dumpbase dumpvect
-PARAMS_LIBS = -g -lm -lrt -lfftw3f -DUSE_FFTW -DLIBCSDR_GPL
+PARAMS_LIBS = -g -lm -lrt -lfftw3f -DUSE_FFTW -DLIBCSDR_GPL -DUSE_IMA_ADPCM
 PARAMS_SO = -fpic  
 PARAMS_MISC = -Wno-unused-result
+FFTW_PACKAGE = fftw-3.3.3
 
 all: clean-vect
 	@echo NOTE: you may have to manually edit Makefile to optimize for your CPU \(especially if you compile on ARM, please edit PARAMS_NEON\).
@@ -64,3 +65,22 @@ install:
 uninstall:
 	rm /usr/lib/libcsdr.so /usr/bin/csdr /usr/bin/csdr-fm
 	ldconfig
+emcc-clean:
+	-rm sdr.js/sdr.js
+	-rm sdr.js/sdrjs-compiled.js
+	-rm -rf sdr.js/$(FFTW_PACKAGE)
+emcc-get-deps:
+	echo "getting and compiling fftw3 with emscripten..."
+	cd sdr.js; \
+	wget http://fftw.org/$(FFTW_PACKAGE).tar.gz; \
+	tar -xvf $(FFTW_PACKAGE).tar.gz; \
+	rm $(FFTW_PACKAGE).tar.gz; \
+	cd $(FFTW_PACKAGE); \
+	emconfigure ./configure --enable-float --disable-fortran --prefix=`pwd`/emscripten-install --libdir=`pwd`/emscripten-lib; \
+	emmake make; \
+	emmake make install
+emcc:
+	emcc -O3 -Isdr.js/$(FFTW_PACKAGE)/api -Lsdr.js/$(FFTW_PACKAGE)/emscripten-lib -o sdr.js/sdrjs-compiled.js fft_fftw.c libcsdr_wrapper.c -DLIBCSDR_GPL -DUSE_IMA_ADPCM -DUSE_FFTW -lfftw3f -s EXPORTED_FUNCTIONS="`python sdr.js/exported_functions.py`"
+	cat sdr.js/sdrjs-header.js sdr.js/sdrjs-compiled.js sdr.js/sdrjs-footer.js > sdr.js/sdr.js
+emcc-beautify:
+	bash -c 'type js-beautify >/dev/null 2>&1; if [ $$? -eq 0 ]; then js-beautify sdr.js/sdr.js >sdr.js/sdr.js.beautiful; mv sdr.js/sdr.js.beautiful sdr.js/sdr.js; fi'
diff --git a/README.md b/README.md
index c306814dbf0f442eba2d91edd784236eb4843d51..b0c9d7910cf2be2954c0fcb7ea83bdac710d5eb4 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,8 @@ Most of the code is available under the permissive BSD license, with some option
 - The code of *libcsdr* was intended to be easy to follow.
 - *libcsdr* was designed to use auto-vectorization available in *gcc*. It means that it can achieve some speedup by taking advantage of SIMD command sets available in today's CPUs (e.g. SSE on x86 and NEON on ARM).
 
+Moreover, *libcsdr* serves as the base for the new, experimental <a href="#sdr.js">sdr.js</a>, which takes Software Defined Radio DSP to today's web browsers that provide JavScript JIT compilation. 
+
 How to compile
 --------------
 The project was only tested on Linux. It has the following dependencies: `libfftw3-dev`
@@ -155,15 +157,33 @@ It multiplies all samples by `gain`.
 
 It copies the input to the output.
 
+	none
+
+The `csdr` process just exits with 0.
+
 	yes_f <to_repeat> [buf_times]
 
 It outputs continously the `to_repeat` float number. 
 If `buf_times` is not given, it never stops.
 Else, after outputing `buf_times` number of buffers (the size of which is stated in the `BUFSIZE` macro), it exits.
 
+	detect_nan_ff
+
+Along with copying its input samples to the output, it prints a warning message to *stderr* if it finds any IEEE floating point NaN values among the samples.
+
+	floatdump_f
+
+It prints any floating point input samples. 
+The format string used is `"%g "`.
+
+	flowcontrol <data_rate> <reads_per_second>
+
+It limits the data rate of a stream to a given `data_rate` number of bytes per second.
+It copies `data_rate / reads_per_second` bytes from the input to the output, doing it `reads_per_second` times every second.
+
 	shift_math_cc <rate>
 
-It shifts the complex spectrum by `rate`.
+It shifts the signal in the frequency domain by `rate`.
 `rate` is a floating point number between -0.5 and 0.5. 
 `rate` is relative to the sampling rate. 
 
@@ -179,6 +199,17 @@ Internally, this function uses trigonometric addition formulas to generate sine
 
 This function was used to test the accuracy of the method above.
 
+	shift_table_cc <rate> [table_size]
+
+Operation is the same as with `shift_math_cc`.
+Internally, this function uses a look-up table (LUT) to recall the values of the sine function (for the first quadrant).
+The higher the table size is, the smaller the phase error is.
+
+	decimating_shift_addition_cc <rate> [decimation]
+
+It shifts the input signal in the frequency domain, and also decimates it, without filtering. It will be useful as a part of the FFT channelizer implementation (to be done).
+It cannot be used as a channelizer by itself, use `fir_decimate_cc` instead.
+
 	dcblock_ff
 
 This is a DC blocking IIR filter.
@@ -214,7 +245,7 @@ It uses fixed filters so it works only on predefined sample rates, for the actua
 
 It is an AM demodulator that uses `sqrt`. On some architectures `sqrt` can be directly calculated by dedicated CPU instructions, but on others it may be slower. 
 
-amdemod_estimator_cf
+	amdemod_estimator_cf
 
 It is an AM demodulator that uses an estimation method that is faster but less accurate than `amdemod_cf`.
 
@@ -296,10 +327,28 @@ FFTW can be faster if we let it optimalize a while before starting the first tra
 It measures the time taken to process `fft_cycles` transforms of `fft_size`.
 It lets FFTW optimalize if used with the `--benchmark` switch.
 
-	lowpower_cf [add_db]
+	logpower_cf [add_db]
 
 Calculates `10*log10(i^2+q^2)+add_db` for the input complex samples. It is useful for drawing power spectrum graphs.
 
+	encode_ima_adpcm_i16_u8
+
+Encodes the audio stream to IMA ADPCM, which decreases the size to 25% of the original.
+
+	decode_ima_adpcm_u8_i16
+
+Decodes the audio stream from IMA ADPCM.
+
+	compress_fft_adpcm_f_u8 <fft_size>
+
+Encodes the FFT output vectors of `fft_size`. It should be used on the data output from `logpower_cf`.
+It resets the ADPCM encoder at the beginning of every vector, and to compensate it, `COMPRESS_FFT_PAD_N` samples are added at beginning (these equal to the first relevant sample).
+The actual number of padding samples can be determined by running `cat csdr.c | grep "define COMPRESS_FFT_PAD_N"`.
+
+	fft_exchange_sides_ff <fft_size>
+
+It exchanges the first and second part of the FFT vector, to prepare it for the waterfall/spectrum display. It should operate on the data output from `logpower_cf`.
+
 #### Control via pipes
 
 Some parameters can be changed while the `csdr` process is running. To achieve this, some `csdr` functions have special parameters. You have to supply a fifo previously created by the `mkfifo` command. Processing will only start after the first control command has been received by `csdr` over the FIFO.
@@ -326,6 +375,28 @@ E.g. you can send `-0.05 0.02\n`
 
 `csdr` was tested with GNU Radio Companion flowgraphs. These flowgraphs are available under the directory `grc_tests`, and they require the <a href="https://github.com/simonyiszk/gr-ha5kfu">gr-ha5kfu</a> set of blocks for GNU Radio.  
 
+## [sdr.js] (#sdr.js)
+
+*sdr.js* is *libcsdr* compiled to JavaScript code with *Emscripten*. Nowadays JavaScript runs quite fast in browsers, as all major browser vendors included JavaScript JIT machines into their product. You can find a <a href="https://kripken.github.io/mloc_emscripten_talk/cppcon.html">great introductory slideshow here</a> about *Emscripten*.
+
+The purpose of *sdr.js* is to make SDR DSP processing available in the web browser. However, it is not easy to use in production yet. By now, only those functions have wrappers that the front-end of OpenWebRX uses.
+
+To compile *sdr.js*, you will need <a href="http://emscripten.org/">emscripten</a>. (It turns out that *emscripten* is already included in Ubuntu repositories.)
+
+To install and build dependencies (for now, only FFTW3):
+
+	make emcc-get-deps
+
+To compile *sdr.js* (which will be created in the `sdr.js` subdirectory):
+
+	make emcc
+
+You can test *sdr.js* by opening *sdr.html*. It contains a test for *firdes_lowpass_f* for this time.
+
+To remove *sdr.js* and the compiled dependencies:
+
+	make emcc-clean
+
 ## [Licensing] (#licensing)
 
 Most of the code of `libcsdr` is under BSD license.  
diff --git a/csdr.c b/csdr.c
index 6aea2a85e9a8c34c6674b59d387b93a9fef5d919..905a879ab987b984942a9f04172da50ed0364be0 100644
--- a/csdr.c
+++ b/csdr.c
@@ -44,6 +44,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdarg.h> 
 #include "libcsdr.h"
 #include "libcsdr_gpl.h"
+#include "ima_adpcm.h"
+#include <sched.h>
+#include <math.h>
 
 char usage[]=
 "csdr - a simple commandline tool for Software Defined Radio receiver DSP.\n\n"
@@ -59,10 +62,16 @@ char usage[]=
 "    limit_ff [max_amplitude]\n"
 "    gain_ff <gain>\n"
 "    clone\n"
+"    none\n"
 "    yes_f <to_repeat> [buf_times]\n"
+"    detect_nan_ff\n"
+"    floatdump_f\n"
+"    flowcontrol <data_rate> <reads_per_second>\n"
 "    shift_math_cc <rate>\n"
 "    shift_addition_cc <rate>\n"
 "    shift_addition_cc_test\n"
+"    shift_table_cc <rate> [table_size]\n"
+"    decimating_shift_addition_cc <rate> [decimation]\n"
 "    dcblock_ff\n"
 "    fastdcblock_ff\n"
 "    fmdemod_atan_cf\n"
@@ -83,12 +92,22 @@ char usage[]=
 "    logpower_cf [add_db]\n"
 "    fft_benchmark <fft_size> <fft_cycles> [--benchmark]\n"
 "    bandpass_fir_fft_cc <low_cut> <high_cut> <transition_bw> [window]\n"
+"    encode_ima_adpcm_i16_u8\n"
+"    decode_ima_adpcm_u8_i16\n"
+"    compress_fft_adpcm_f_u8 <fft_size>\n"
+"    fft_exchange_sides_ff <fft_size>\n"
+"    \n"
 ;
 
-#define BUFSIZE (1024*8)
+#define BUFSIZE (1024)
+#define BIG_BUFSIZE (1024*16)
 //should be multiple of 16! (size of double complex)
 //also, keep in mind that shift_addition_cc works better the smaller this buffer is.
 
+#define YIELD_EVERY_N_TIMES 3
+#define TRY_YIELD if(++yield_counter%YIELD_EVERY_N_TIMES==0) sched_yield()
+unsigned yield_counter=0;
+
 int badsyntax(char* why)
 {
 	if(why==0) fprintf(stderr, "%s", usage);
@@ -113,6 +132,7 @@ int clone()
 		{
 			fread(clone_buffer, sizeof(unsigned char), BUFSIZE, stdin);
 			fwrite(clone_buffer, sizeof(unsigned char), BUFSIZE, stdout);
+			TRY_YIELD;
 		}
 }
 
@@ -121,6 +141,8 @@ int clone()
 #define FWRITE_R fwrite(output_buffer, sizeof(float), BUFSIZE, stdout)
 #define FWRITE_C fwrite(output_buffer, sizeof(float)*2, BUFSIZE, stdout)
 #define FEOF_CHECK if(feof(stdin)) return 0
+#define BIG_FREAD_C fread(input_buffer, sizeof(float)*2, BIG_BUFSIZE, stdin)
+#define BIG_FWRITE_C fwrite(output_buffer, sizeof(float)*2, BIG_BUFSIZE, stdout)
 
 int init_fifo(int argc, char *argv[])
 {
@@ -179,12 +201,12 @@ int read_fifo_ctl(int fd, char* format, ...)
 }
 
 int main(int argc, char *argv[])
-{
-	static float input_buffer[BUFSIZE*2];
-	static unsigned char buffer_u8[BUFSIZE*2];
-	static float output_buffer[BUFSIZE*2];
-	static short buffer_i16[BUFSIZE*2];
-	static float temp_f[BUFSIZE*4];
+{	
+	static float input_buffer[BIG_BUFSIZE*2];
+	static unsigned char buffer_u8[BIG_BUFSIZE*2];
+	static float output_buffer[BIG_BUFSIZE*2];
+	static short buffer_i16[BIG_BUFSIZE*2];
+	static float temp_f[BIG_BUFSIZE*4];
 	if(argc<=1) return badsyntax(0);
 	if(!strcmp(argv[1],"--help")) return badsyntax(0);
 	if(!strcmp(argv[1],"convert_u8_f"))
@@ -195,6 +217,7 @@ int main(int argc, char *argv[])
 			fread(buffer_u8, sizeof(unsigned char), BUFSIZE, stdin);
 			convert_u8_f(buffer_u8, output_buffer, BUFSIZE);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"convert_f_u8")) //not tested
@@ -205,6 +228,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			convert_f_u8(input_buffer, buffer_u8, BUFSIZE);
 			fwrite(buffer_u8, sizeof(unsigned char), BUFSIZE, stdout);
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"convert_f_i16"))
@@ -215,6 +239,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			convert_f_i16(input_buffer, buffer_i16, BUFSIZE);
 			fwrite(buffer_i16, sizeof(short), BUFSIZE, stdout);
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"convert_i16_f")) //not tested
@@ -225,6 +250,7 @@ int main(int argc, char *argv[])
 			fread(buffer_i16, sizeof(short), BUFSIZE, stdin);
 			convert_i16_f(buffer_i16, output_buffer, BUFSIZE);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"realpart_cf"))
@@ -235,6 +261,7 @@ int main(int argc, char *argv[])
 			FREAD_C;
 			for(int i=0;i<BUFSIZE;i++) output_buffer[i]=iof(input_buffer,i);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"clipdetect_ff"))
@@ -245,6 +272,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			clipdetect_ff(input_buffer, BUFSIZE);
 			fwrite(input_buffer, sizeof(float), BUFSIZE, stdout);
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"gain_ff"))
@@ -258,6 +286,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			gain_ff(input_buffer, output_buffer, BUFSIZE, gain);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"clone"))
@@ -274,6 +303,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			limit_ff(input_buffer, output_buffer, BUFSIZE, max_amplitude);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"yes_f"))
@@ -284,7 +314,11 @@ int main(int argc, char *argv[])
 		int buf_times = 0;
 		if(argc>=4) sscanf(argv[3],"%d",&buf_times);
 		for(int i=0;i<BUFSIZE;i++) output_buffer[i]=to_repeat;
-		for(int i=0;(!buf_times)||i<buf_times;i++) fwrite(output_buffer, sizeof(float), BUFSIZE, stdout);
+		for(int i=0;(!buf_times)||i<buf_times;i++) 
+		{ 
+			fwrite(output_buffer, sizeof(float), BUFSIZE, stdout); 
+			TRY_YIELD; 
+		}
 		return 0;
 	}
 	if(!strcmp(argv[1],"shift_math_cc"))
@@ -299,13 +333,60 @@ int main(int argc, char *argv[])
 			if(!FREAD_C) break;
 			starting_phase=shift_math_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, rate, starting_phase);
 			FWRITE_C;
+			TRY_YIELD;
 		}
 		return 0;
 	}
 	//speed tests: 
 	//csdr yes_f 1 1000000 | time csdr shift_math_cc 0.2 >/dev/null
 	//csdr yes_f 1 1000000 | time csdr shift_addition_cc 0.2 >/dev/null
+	//csdr yes_f 1 1000000 | time csdr shift_table_cc 0.2 >/dev/null
+
+	if(!strcmp(argv[1],"shift_table_cc"))
+	{
+		if(argc<=2) return badsyntax("need required parameter (rate)"); 
+		float starting_phase=0;
+		float rate;
+		int table_size=65536;
+		sscanf(argv[2],"%g",&rate);
+		if(argc>3) sscanf(argv[3],"%d",&table_size);
+		shift_table_data_t table_data=shift_table_init(table_size);
+		fprintf(stderr,"shift_table_cc: LUT initialized\n");
+		for(;;)
+		{
+			FEOF_CHECK;
+			if(!BIG_FREAD_C) break;
+			starting_phase=shift_table_cc((complexf*)input_buffer, (complexf*)output_buffer, BIG_BUFSIZE, rate, table_data, starting_phase);
+			BIG_FWRITE_C;
+			TRY_YIELD;
+		}
+		return 0;
+	}
+
 #ifdef LIBCSDR_GPL
+	if(!strcmp(argv[1],"decimating_shift_addition_cc"))
+	{
+		if(argc<=2) return badsyntax("need required parameter (rate)"); 
+		float starting_phase=0;
+		float rate;
+		int decimation=1;
+		sscanf(argv[2],"%g",&rate);
+		if(argc>3) sscanf(argv[3],"%d",&decimation);
+		shift_addition_data_t d=decimating_shift_addition_init(rate, decimation);
+		decimating_shift_addition_status_t s;
+		s.decimation_remain=0;
+		s.starting_phase=0;
+		for(;;)
+		{
+			FEOF_CHECK;
+			if(!BIG_FREAD_C) break;
+			s=decimating_shift_addition_cc((complexf*)input_buffer, (complexf*)output_buffer, BIG_BUFSIZE, d, decimation, s);
+			fwrite(output_buffer, sizeof(float)*2, s.output_size, stdout);
+			TRY_YIELD;
+		}
+		return 0;
+	}
+
 	if(!strcmp(argv[1],"shift_addition_cc"))
 	{
 		float starting_phase=0;
@@ -329,10 +410,11 @@ int main(int argc, char *argv[])
 			for(;;)
 			{
 				FEOF_CHECK;
-				if(!FREAD_C) break;
-				starting_phase=shift_addition_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, data, starting_phase);
-				FWRITE_C;
+				if(!BIG_FREAD_C) break;
+				starting_phase=shift_addition_cc((complexf*)input_buffer, (complexf*)output_buffer, BIG_BUFSIZE, data, starting_phase);
+				BIG_FWRITE_C;
 				if(read_fifo_ctl(fd,"%g\n",&rate)) break;
+				TRY_YIELD;
 			}
 		}
 		return 0;
@@ -357,6 +439,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			dcp=dcblock_ff(input_buffer, output_buffer, BUFSIZE, 0, dcp);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 
@@ -372,6 +455,7 @@ int main(int argc, char *argv[])
 			fread(dcblock_buffer, sizeof(float), dcblock_bufsize, stdin);
 			last_dc_level=fastdcblock_ff(dcblock_buffer, dcblock_buffer, dcblock_bufsize, last_dc_level);
 			fwrite(dcblock_buffer, sizeof(float), dcblock_bufsize, stdout);
+			TRY_YIELD;
 		}
 	}
 
@@ -385,6 +469,7 @@ int main(int argc, char *argv[])
 			if(feof(stdin)) return 0;
 			last_phase=fmdemod_atan_cf((complexf*)input_buffer, output_buffer, BUFSIZE, last_phase);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"fmdemod_quadri_cf"))
@@ -398,6 +483,7 @@ int main(int argc, char *argv[])
 			FREAD_C;
 			last_sample=fmdemod_quadri_cf((complexf*)input_buffer, output_buffer, BUFSIZE, temp_f, last_sample);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"fmdemod_quadri_novect_cf"))
@@ -411,6 +497,7 @@ int main(int argc, char *argv[])
 			FREAD_C;
 			last_sample=fmdemod_quadri_novect_cf((complexf*)input_buffer, output_buffer, BUFSIZE, last_sample);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"deemphasis_wfm_ff"))
@@ -421,7 +508,6 @@ int main(int argc, char *argv[])
 		float tau;
 		sscanf(argv[3],"%g",&tau);
 		fprintf(stderr,"deemphasis_wfm_ff: tau = %g, sample_rate = %d\n",tau,sample_rate);
-		
 		float last_output=0;
 		for(;;)
 		{
@@ -429,8 +515,42 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			last_output=deemphasis_wfm_ff(input_buffer, output_buffer, BUFSIZE, tau, sample_rate, last_output);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
+
+	if(!strcmp(argv[1],"detect_nan_ff"))
+	{
+		for(;;)
+		{
+			FEOF_CHECK;
+			FREAD_R;
+			int nan_detect=0;			
+			for(int i=0; i<BUFSIZE;i++) 
+			{
+				if(is_nan(input_buffer[i])) 
+				{ 
+					nan_detect=1; 
+					break; 
+				}
+			}
+			if(nan_detect) fprintf(stderr, "detect_nan_f: NaN detected!\n");
+			fwrite(input_buffer, sizeof(float), BUFSIZE, stdout);
+			TRY_YIELD;
+		}	
+	}
+
+	if(!strcmp(argv[1],"floatdump_f"))
+	{
+		for(;;)
+		{
+			FEOF_CHECK;
+			FREAD_R;
+			for(int i=0; i<BUFSIZE;i++) fprintf(stderr, "%g ",input_buffer[i]);
+			TRY_YIELD;
+		}
+		
+	}
 	if(!strcmp(argv[1],"deemphasis_nfm_ff"))
 	{
 		if(argc<=2) return badsyntax("need required parameter (sample rate)"); 
@@ -446,6 +566,7 @@ int main(int argc, char *argv[])
 			if(!processed) return badsyntax("deemphasis_nfm_ff: invalid sample rate (this function works only with specific sample rates).");  
 			memmove(input_buffer,input_buffer+processed,(BUFSIZE-processed)*sizeof(float)); //memmove lets the source and destination overlap
 			fwrite(output_buffer, sizeof(float), processed, stdout);
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"amdemod_cf"))
@@ -456,6 +577,7 @@ int main(int argc, char *argv[])
 			FREAD_C;
 			amdemod_cf((complexf*)input_buffer, output_buffer, BUFSIZE);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"amdemod_estimator_cf"))
@@ -466,6 +588,7 @@ int main(int argc, char *argv[])
 			FREAD_C;
 			amdemod_estimator_cf((complexf*)input_buffer, output_buffer, BUFSIZE, 0., 0.);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 	if(!strcmp(argv[1],"fir_decimate_cc"))
@@ -496,13 +619,14 @@ int main(int argc, char *argv[])
 		for(;;)
 		{
 			FEOF_CHECK;
-			output_size=fir_decimate_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, factor, taps, taps_length);
+			output_size=fir_decimate_cc((complexf*)input_buffer, (complexf*)output_buffer, BIG_BUFSIZE, factor, taps, taps_length);
 			fwrite(output_buffer, sizeof(complexf), output_size, stdout);
 			fflush(stdout);
+			TRY_YIELD;
 			input_skip=factor*output_size;
-			memmove((complexf*)input_buffer,((complexf*)input_buffer)+input_skip,(BUFSIZE-input_skip)*sizeof(complexf)); //memmove lets the source and destination overlap
-			fread(((complexf*)input_buffer)+(BUFSIZE-input_skip), sizeof(complexf), input_skip, stdin);			
-			//fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BUFSIZE-input_skip),(BUFSIZE-input_skip));
+			memmove((complexf*)input_buffer,((complexf*)input_buffer)+input_skip,(BIG_BUFSIZE-input_skip)*sizeof(complexf)); //memmove lets the source and destination overlap
+			fread(((complexf*)input_buffer)+(BIG_BUFSIZE-input_skip), sizeof(complexf), input_skip, stdin);			
+			//fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BIG_BUFSIZE-input_skip),(BIG_BUFSIZE-input_skip));
 		}
 	}
 	/*if(!strcmp(argv[1],"ejw_test"))
@@ -639,6 +763,7 @@ int main(int argc, char *argv[])
 			FREAD_R;
 			last_gain=agc_ff(input_buffer, output_buffer, BUFSIZE, reference, attack_rate, decay_rate, max_gain, hang_time, attack_wait, filter_alpha, last_gain);
 			FWRITE_R;
+			TRY_YIELD;
 		}
 	}
 #endif
@@ -663,6 +788,7 @@ int main(int argc, char *argv[])
 			fread(input.buffer_input, sizeof(float), input.input_size, stdin);
 			fastagc_ff(&input, agc_output_buffer); 
 			fwrite(agc_output_buffer, sizeof(float), input.input_size, stdout);
+			TRY_YIELD;
 		}
 	}
 
@@ -715,6 +841,7 @@ int main(int argc, char *argv[])
 			d=rational_resampler_ff(input_buffer, resampler_output_buffer, BUFSIZE, interpolation, decimation, taps, taps_length, d.last_taps_delay);
 			//fprintf(stderr,"resampled %d %d, %d\n",d.output_size, d.input_processed, d.input_processed);
 			fwrite(resampler_output_buffer, sizeof(float), d.output_size, stdout);
+			TRY_YIELD;
 		}
 	}
 
@@ -754,6 +881,7 @@ int main(int argc, char *argv[])
 			fread(input_buffer+(BUFSIZE-d.input_processed), sizeof(float), d.input_processed, stdin);
 			d = fractional_decimator_ff(input_buffer, output_buffer, BUFSIZE, rate, taps, taps_length, d);
 			fwrite(output_buffer, sizeof(float), d.output_size, stdout);
+			TRY_YIELD;
 		}
 	}
 
@@ -823,6 +951,7 @@ int main(int argc, char *argv[])
 				);
 			}
 			else fwrite(output, sizeof(complexf), fft_size, stdout);
+			TRY_YIELD;
 		}
 	}
 	#define LOGPOWERCF_BUFSIZE 64
@@ -837,10 +966,60 @@ int main(int argc, char *argv[])
 			fread(input_buffer, sizeof(complexf), LOGPOWERCF_BUFSIZE, stdin);
 			logpower_cf((complexf*)input_buffer,output_buffer,LOGPOWERCF_BUFSIZE,add_db);
 			fwrite(output_buffer, sizeof(float), LOGPOWERCF_BUFSIZE, stdout);
+			//bufsize is so small, I don't dare to TRY_YIELD
+		}
+	}
+
+	if(!strcmp(argv[1],"fft_exchange_sides_ff"))
+	{
+		if(argc<=2) return badsyntax("need required parameters (fft_size)"); 
+		int fft_size;
+		sscanf(argv[2],"%d",&fft_size);
+		float* input_buffer_s1 = (float*)malloc(sizeof(float)*fft_size/2);
+		float* input_buffer_s2 = (float*)malloc(sizeof(float)*fft_size/2);
+		for(;;)
+		{
+			FEOF_CHECK;
+			fread(input_buffer_s1, sizeof(float), fft_size/2, stdin);
+			fread(input_buffer_s2, sizeof(float), fft_size/2, stdin);
+			fwrite(input_buffer_s2, sizeof(float), fft_size/2, stdout);
+			fwrite(input_buffer_s1, sizeof(float), fft_size/2, stdout);
+			TRY_YIELD;
 		}
 	}
 
 
+#ifdef USE_IMA_ADPCM
+
+#define COMPRESS_FFT_PAD_N 10
+//We will pad the FFT at the beginning, with the first value of the input data, COMPRESS_FFT_PAD_N times.
+//No, this is not advanced DSP, just the ADPCM codec produces some gabarge samples at the beginning, 
+//so we just add data to become garbage and get skipped. 
+//COMPRESS_FFT_PAD_N should be even.
+
+	if(!strcmp(argv[1],"compress_fft_adpcm_f_u8"))
+	{
+		if(argc<=2) return badsyntax("need required parameters (fft_size)"); 
+		int fft_size;
+		sscanf(argv[2],"%d",&fft_size);
+		int real_data_size=fft_size+COMPRESS_FFT_PAD_N;
+		float* input_buffer_cwa = (float*)malloc(sizeof(float)*real_data_size);
+		short* temp_buffer_cwa = (short*)malloc(sizeof(short)*real_data_size);
+		unsigned char* output_buffer_cwa = (unsigned char*)malloc(sizeof(unsigned char)*(real_data_size/2));
+		ima_adpcm_state_t d;
+		d.index=d.previousValue=0;
+		for(;;)
+		{
+			FEOF_CHECK;
+			fread(input_buffer_cwa+COMPRESS_FFT_PAD_N, sizeof(float), fft_size, stdin);
+			for(int i=0;i<COMPRESS_FFT_PAD_N;i++) input_buffer_cwa[i]=input_buffer_cwa[COMPRESS_FFT_PAD_N]; //do padding
+			for(int i=0;i<real_data_size;i++) temp_buffer_cwa[i]=input_buffer_cwa[i]*100; //convert float dB values to short
+			encode_ima_adpcm_i16_u8(temp_buffer_cwa, output_buffer_cwa, real_data_size, d); //we always return to original d at any new buffer
+			fwrite(output_buffer_cwa, sizeof(unsigned char), real_data_size/2, stdout);
+			TRY_YIELD;
+		}
+	}
+#endif
 
 #define TIME_TAKEN(start,end) ((end.tv_sec-start.tv_sec)+(end.tv_nsec-start.tv_nsec)/1e9)
 
@@ -955,11 +1134,65 @@ int main(int argc, char *argv[])
 				apply_fir_fft_cc (plan_forward, plan_inverse, taps_fft, last_overlap, overlap_length);
 				int returned=fwrite(plan_inverse->output, sizeof(complexf), input_size, stdout);
 				if(read_fifo_ctl(fd,"%g %g\n",&low_cut,&high_cut)) break;
+				TRY_YIELD;
 			}
 		}
 
 	}
 
+#ifdef USE_IMA_ADPCM
+#define IMA_ADPCM_BUFSIZE BUFSIZE
+
+	if(!strcmp(argv[1],"encode_ima_adpcm_i16_u8"))
+	{
+		ima_adpcm_state_t d;
+		d.index=d.previousValue=0;
+		for(;;)
+		{
+			FEOF_CHECK;
+			fread(buffer_i16, sizeof(short), IMA_ADPCM_BUFSIZE, stdin);
+			d=encode_ima_adpcm_i16_u8(buffer_i16, buffer_u8, IMA_ADPCM_BUFSIZE, d);
+			fwrite(buffer_u8, sizeof(unsigned char), IMA_ADPCM_BUFSIZE/2, stdout);
+			TRY_YIELD;
+		}
+	}
+
+	if(!strcmp(argv[1],"decode_ima_adpcm_u8_i16"))
+	{
+		ima_adpcm_state_t d;
+		d.index=d.previousValue=0;
+		for(;;)
+		{
+			FEOF_CHECK;
+			fread(buffer_u8, sizeof(unsigned char), IMA_ADPCM_BUFSIZE/2, stdin);
+			d=decode_ima_adpcm_u8_i16(buffer_u8, buffer_i16, IMA_ADPCM_BUFSIZE/2, d);
+			fwrite(buffer_i16, sizeof(short), IMA_ADPCM_BUFSIZE, stdout);
+			TRY_YIELD;
+		}
+	}
+#endif
+
+	if(!strcmp(argv[1],"flowcontrol"))
+	{
+		if(argc<=3) return badsyntax("need required parameters (data_rate, reads_per_seconds)"); 
+		int data_rate;
+		sscanf(argv[2],"%d",&data_rate);
+		int reads_per_second;
+		sscanf(argv[3],"%d",&reads_per_second);
+		int flowcontrol_bufsize=ceil(1.*(double)data_rate/reads_per_second);
+		unsigned char* flowcontrol_buffer = (unsigned char*)malloc(sizeof(unsigned char)*flowcontrol_bufsize);
+		int flowcontrol_sleep=floor(1000000./reads_per_second);
+		fprintf(stderr, "flowcontrol: flowcontrol_bufsize = %d, flowcontrol_sleep = %d\n", flowcontrol_bufsize, flowcontrol_sleep);
+		for(;;)
+		{
+			FEOF_CHECK;
+			fread(flowcontrol_buffer, sizeof(unsigned char), flowcontrol_bufsize, stdin);
+			fwrite(flowcontrol_buffer, sizeof(unsigned char), flowcontrol_bufsize, stdout);
+			usleep(flowcontrol_sleep);
+			TRY_YIELD;
+		}
+	}
+
 	if(!strcmp(argv[1],"none"))
 	{
 		return 0;
diff --git a/grc_tests/test_ima_adpcm.grc b/grc_tests/test_ima_adpcm.grc
new file mode 100644
index 0000000000000000000000000000000000000000..c0b77f86f86265da3a13fca82fde9b7eb8242a01
--- /dev/null
+++ b/grc_tests/test_ima_adpcm.grc
@@ -0,0 +1,844 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.5'?>
+<flow_graph>
+  <timestamp>Sun Jan 25 13:25:30 2015</timestamp>
+  <block>
+    <key>options</key>
+    <param>
+      <key>id</key>
+      <value>top_block</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value></value>
+    </param>
+    <param>
+      <key>author</key>
+      <value></value>
+    </param>
+    <param>
+      <key>description</key>
+      <value></value>
+    </param>
+    <param>
+      <key>window_size</key>
+      <value>1280, 1024</value>
+    </param>
+    <param>
+      <key>generate_options</key>
+      <value>wx_gui</value>
+    </param>
+    <param>
+      <key>category</key>
+      <value>Custom</value>
+    </param>
+    <param>
+      <key>run_options</key>
+      <value>prompt</value>
+    </param>
+    <param>
+      <key>run</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>max_nouts</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>realtime_scheduling</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(10, 10)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable</key>
+    <param>
+      <key>id</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>32000</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(176, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>amp</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>0.5</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(544, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>analog_sig_source_x</key>
+    <param>
+      <key>id</key>
+      <value>analog_sig_source_x_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>waveform</key>
+      <value>analog.GR_COS_WAVE</value>
+    </param>
+    <param>
+      <key>freq</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>amp</key>
+      <value>amp</value>
+    </param>
+    <param>
+      <key>offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(8, 163)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>blocks_throttle</key>
+    <param>
+      <key>id</key>
+      <value>blocks_throttle_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>samples_per_second</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>ignoretag</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(176, 195)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot of Original Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,0</value>
+    </param>
+    <param>
+      <key>trig_mode</key>
+      <value>wxgui.TRIG_MODE_AUTO</value>
+    </param>
+    <param>
+      <key>y_axis_label</key>
+      <value>Counts</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(352, 331)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>nb0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Scope', 'FFT']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(272, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>notebook</key>
+    <param>
+      <key>id</key>
+      <value>nb1</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
+    </param>
+    <param>
+      <key>labels</key>
+      <value>['Scope', 'FFT']</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(272, 99)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot of Original Signal</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,1</value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(352, 459)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot of Processed Signal (csdr)</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb1,0</value>
+    </param>
+    <param>
+      <key>trig_mode</key>
+      <value>wxgui.TRIG_MODE_AUTO</value>
+    </param>
+    <param>
+      <key>y_axis_label</key>
+      <value>Counts</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(760, 171)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot of Processed Signal (csdr)</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb1,1</value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(760, 299)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>ha5kfu_execproc_xx</key>
+    <param>
+      <key>id</key>
+      <value>ha5kfu_execproc_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ff</value>
+    </param>
+    <param>
+      <key>commandline</key>
+      <value>csdr convert_f_i16 | csdr encode_ima_adpcm_i16_u8 | csdr decode_ima_adpcm_u8_i16 | csdr convert_i16_f</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(448, 195)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>variable_slider</key>
+    <param>
+      <key>id</key>
+      <value>freq</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>label</key>
+      <value></value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>1000</value>
+    </param>
+    <param>
+      <key>min</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>max</key>
+      <value>samp_rate/2</value>
+    </param>
+    <param>
+      <key>num_steps</key>
+      <value>100</value>
+    </param>
+    <param>
+      <key>style</key>
+      <value>wx.SL_HORIZONTAL</value>
+    </param>
+    <param>
+      <key>converver</key>
+      <value>float_converter</value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value></value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(424, 11)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <connection>
+    <source_block_id>analog_sig_source_x_0</source_block_id>
+    <sink_block_id>blocks_throttle_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blocks_throttle_0</source_block_id>
+    <sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blocks_throttle_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blocks_throttle_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+</flow_graph>
diff --git a/grc_tests/test_rational_resampler.grc b/grc_tests/test_rational_resampler.grc
index 7bb2e71da0dc326131edd8afa38de7e48ad9e37a..fe8e838cedf055ce56459a7596454da9af359905 100644
--- a/grc_tests/test_rational_resampler.grc
+++ b/grc_tests/test_rational_resampler.grc
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='ASCII'?>
 <?grc format='1' created='3.7.5'?>
 <flow_graph>
-  <timestamp>Tue Nov 25 18:15:25 2014</timestamp>
+  <timestamp>Tue Mar 17 19:40:27 2015</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -77,7 +77,7 @@
     </param>
     <param>
       <key>value</key>
-      <value>2</value>
+      <value>1</value>
     </param>
     <param>
       <key>alias</key>
@@ -104,7 +104,7 @@
     </param>
     <param>
       <key>value</key>
-      <value>5</value>
+      <value>4</value>
     </param>
     <param>
       <key>alias</key>
@@ -939,49 +939,6 @@
       <value>0</value>
     </param>
   </block>
-  <block>
-    <key>ha5kfu_execproc_xx</key>
-    <param>
-      <key>id</key>
-      <value>ha5kfu_execproc_xx_0</value>
-    </param>
-    <param>
-      <key>_enabled</key>
-      <value>True</value>
-    </param>
-    <param>
-      <key>type</key>
-      <value>ff</value>
-    </param>
-    <param>
-      <key>commandline</key>
-      <value>"csdr rational_resampler_ff %d %d 0.05"%(interpolation,decimation)</value>
-    </param>
-    <param>
-      <key>alias</key>
-      <value></value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(752, 195)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
   <block>
     <key>notebook</key>
     <param>
@@ -1076,6 +1033,49 @@
       <value>0</value>
     </param>
   </block>
+  <block>
+    <key>ha5kfu_execproc_xx</key>
+    <param>
+      <key>id</key>
+      <value>ha5kfu_execproc_xx_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>ff</value>
+    </param>
+    <param>
+      <key>commandline</key>
+      <value>"csdr rational_resampler_ff %d %d 0.05"%(interpolation,decimation)</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(752, 195)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
   <connection>
     <source_block_id>blocks_throttle_0</source_block_id>
     <sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
diff --git a/grc_tests/test_shift.grc b/grc_tests/test_shift.grc
index 5f5a9ab51adc09ba81fffd94ff91a723f7e20c71..9fc1eb78104e09d2f9403288ffd2cd8fa2510e20 100644
--- a/grc_tests/test_shift.grc
+++ b/grc_tests/test_shift.grc
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='ASCII'?>
 <?grc format='1' created='3.7.5'?>
 <flow_graph>
-  <timestamp>Sat Nov 15 22:24:14 2014</timestamp>
+  <timestamp>Thu Jan 15 18:51:48 2015</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -69,7 +69,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>samp_rate</value>
+      <value>rate</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -77,7 +77,7 @@
     </param>
     <param>
       <key>value</key>
-      <value>250e3</value>
+      <value>-0.055</value>
     </param>
     <param>
       <key>alias</key>
@@ -85,7 +85,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(10, 170)</value>
+      <value>(8, 195)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -93,58 +93,53 @@
     </param>
   </block>
   <block>
-    <key>analog_sig_source_x</key>
+    <key>variable</key>
     <param>
       <key>id</key>
-      <value>analog_sig_source_x_0</value>
+      <value>decimation</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>type</key>
-      <value>complex</value>
-    </param>
-    <param>
-      <key>samp_rate</key>
-      <value>samp_rate</value>
-    </param>
-    <param>
-      <key>waveform</key>
-      <value>analog.GR_CONST_WAVE</value>
+      <key>value</key>
+      <value>3</value>
     </param>
     <param>
-      <key>freq</key>
-      <value>20000</value>
+      <key>alias</key>
+      <value></value>
     </param>
     <param>
-      <key>amp</key>
-      <value>1</value>
+      <key>_coordinate</key>
+      <value>(16, 267)</value>
     </param>
     <param>
-      <key>offset</key>
+      <key>_rotation</key>
       <value>0</value>
     </param>
+  </block>
+  <block>
+    <key>variable</key>
     <param>
-      <key>alias</key>
-      <value></value>
+      <key>id</key>
+      <value>samp_rate</value>
     </param>
     <param>
-      <key>affinity</key>
-      <value></value>
+      <key>_enabled</key>
+      <value>True</value>
     </param>
     <param>
-      <key>minoutbuf</key>
-      <value>0</value>
+      <key>value</key>
+      <value>250e3</value>
     </param>
     <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
+      <key>alias</key>
+      <value></value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(56, 243)</value>
+      <value>(176, 11)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -152,10 +147,10 @@
     </param>
   </block>
   <block>
-    <key>wxgui_fftsink2</key>
+    <key>analog_sig_source_x</key>
     <param>
       <key>id</key>
-      <value>wxgui_fftsink2_0</value>
+      <value>analog_sig_source_x_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -165,85 +160,45 @@
       <key>type</key>
       <value>complex</value>
     </param>
-    <param>
-      <key>title</key>
-      <value>FFT Plot</value>
-    </param>
     <param>
       <key>samp_rate</key>
       <value>samp_rate</value>
     </param>
     <param>
-      <key>baseband_freq</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>y_per_div</key>
-      <value>10</value>
-    </param>
-    <param>
-      <key>y_divs</key>
-      <value>10</value>
-    </param>
-    <param>
-      <key>ref_level</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>ref_scale</key>
-      <value>2.0</value>
-    </param>
-    <param>
-      <key>fft_size</key>
-      <value>1024</value>
-    </param>
-    <param>
-      <key>fft_rate</key>
-      <value>15</value>
+      <key>waveform</key>
+      <value>analog.GR_CONST_WAVE</value>
     </param>
     <param>
-      <key>peak_hold</key>
-      <value>False</value>
+      <key>freq</key>
+      <value>20000</value>
     </param>
     <param>
-      <key>average</key>
-      <value>False</value>
+      <key>amp</key>
+      <value>1</value>
     </param>
     <param>
-      <key>avg_alpha</key>
+      <key>offset</key>
       <value>0</value>
     </param>
     <param>
-      <key>win</key>
-      <value>None</value>
-    </param>
-    <param>
-      <key>win_size</key>
+      <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>grid_pos</key>
+      <key>affinity</key>
       <value></value>
     </param>
     <param>
-      <key>notebook</key>
-      <value>nb0,0</value>
-    </param>
-    <param>
-      <key>freqvar</key>
-      <value>None</value>
-    </param>
-    <param>
-      <key>alias</key>
-      <value></value>
+      <key>minoutbuf</key>
+      <value>0</value>
     </param>
     <param>
-      <key>affinity</key>
-      <value></value>
+      <key>maxoutbuf</key>
+      <value>0</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(952, 275)</value>
+      <value>(8, 75)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -251,38 +206,42 @@
     </param>
   </block>
   <block>
-    <key>notebook</key>
+    <key>ha5kfu_execproc_xx</key>
     <param>
       <key>id</key>
-      <value>nb0</value>
+      <value>ha5kfu_execproc_xx_0</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>style</key>
-      <value>wx.NB_TOP</value>
+      <key>type</key>
+      <value>cc</value>
     </param>
     <param>
-      <key>labels</key>
-      <value>['shift_math_ff', 'shift_addition_ff', 'original']</value>
+      <key>commandline</key>
+      <value>"csdr shift_math_cc %g"%rate</value>
     </param>
     <param>
-      <key>grid_pos</key>
+      <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>notebook</key>
+      <key>affinity</key>
       <value></value>
     </param>
     <param>
-      <key>alias</key>
-      <value></value>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(256, 27)</value>
+      <value>(488, 251)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -290,10 +249,10 @@
     </param>
   </block>
   <block>
-    <key>wxgui_fftsink2</key>
+    <key>ha5kfu_execproc_xx</key>
     <param>
       <key>id</key>
-      <value>wxgui_fftsink2_0_0</value>
+      <value>ha5kfu_execproc_xx_0_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -301,63 +260,54 @@
     </param>
     <param>
       <key>type</key>
-      <value>complex</value>
-    </param>
-    <param>
-      <key>title</key>
-      <value>FFT Plot</value>
-    </param>
-    <param>
-      <key>samp_rate</key>
-      <value>samp_rate</value>
+      <value>cc</value>
     </param>
     <param>
-      <key>baseband_freq</key>
-      <value>0</value>
+      <key>commandline</key>
+      <value>"csdr shift_addition_cc %g"%rate</value>
     </param>
     <param>
-      <key>y_per_div</key>
-      <value>10</value>
+      <key>alias</key>
+      <value></value>
     </param>
     <param>
-      <key>y_divs</key>
-      <value>10</value>
+      <key>affinity</key>
+      <value></value>
     </param>
     <param>
-      <key>ref_level</key>
+      <key>minoutbuf</key>
       <value>0</value>
     </param>
     <param>
-      <key>ref_scale</key>
-      <value>2.0</value>
-    </param>
-    <param>
-      <key>fft_size</key>
-      <value>1024</value>
+      <key>maxoutbuf</key>
+      <value>0</value>
     </param>
     <param>
-      <key>fft_rate</key>
-      <value>15</value>
+      <key>_coordinate</key>
+      <value>(472, 411)</value>
     </param>
     <param>
-      <key>peak_hold</key>
-      <value>False</value>
+      <key>_rotation</key>
+      <value>0</value>
     </param>
+  </block>
+  <block>
+    <key>notebook</key>
     <param>
-      <key>average</key>
-      <value>False</value>
+      <key>id</key>
+      <value>nb0</value>
     </param>
     <param>
-      <key>avg_alpha</key>
-      <value>0</value>
+      <key>_enabled</key>
+      <value>True</value>
     </param>
     <param>
-      <key>win</key>
-      <value>None</value>
+      <key>style</key>
+      <value>wx.NB_TOP</value>
     </param>
     <param>
-      <key>win_size</key>
-      <value></value>
+      <key>labels</key>
+      <value>['shift_math_cc', 'shift_addition_cc', 'shift_table_cc', 'decimating_shift_addition_cc','original']</value>
     </param>
     <param>
       <key>grid_pos</key>
@@ -365,23 +315,15 @@
     </param>
     <param>
       <key>notebook</key>
-      <value>nb0,2</value>
-    </param>
-    <param>
-      <key>freqvar</key>
-      <value>None</value>
-    </param>
-    <param>
-      <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>affinity</key>
+      <key>alias</key>
       <value></value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(952, 59)</value>
+      <value>(272, 11)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -392,7 +334,7 @@
     <key>wxgui_fftsink2</key>
     <param>
       <key>id</key>
-      <value>wxgui_fftsink2_0_1</value>
+      <value>wxgui_fftsink2_0_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -464,7 +406,7 @@
     </param>
     <param>
       <key>notebook</key>
-      <value>nb0,1</value>
+      <value>nb0,4</value>
     </param>
     <param>
       <key>freqvar</key>
@@ -480,7 +422,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(952, 635)</value>
+      <value>(496, 27)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -531,7 +473,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(232, 275)</value>
+      <value>(224, 107)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -542,7 +484,7 @@
     <key>wxgui_scopesink2</key>
     <param>
       <key>id</key>
-      <value>wxgui_scopesink2_0</value>
+      <value>wxgui_scopesink2_0_0_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -594,7 +536,7 @@
     </param>
     <param>
       <key>notebook</key>
-      <value>nb0,0</value>
+      <value>nb0,2</value>
     </param>
     <param>
       <key>trig_mode</key>
@@ -614,7 +556,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(952, 491)</value>
+      <value>(1080, 899)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -622,10 +564,10 @@
     </param>
   </block>
   <block>
-    <key>wxgui_scopesink2</key>
+    <key>wxgui_fftsink2</key>
     <param>
       <key>id</key>
-      <value>wxgui_scopesink2_0_0</value>
+      <value>wxgui_fftsink2_0_1_0_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -637,35 +579,55 @@
     </param>
     <param>
       <key>title</key>
-      <value>Scope Plot</value>
+      <value>FFT Plot</value>
     </param>
     <param>
       <key>samp_rate</key>
-      <value>samp_rate</value>
+      <value>samp_rate/decimation</value>
     </param>
     <param>
-      <key>v_scale</key>
+      <key>baseband_freq</key>
       <value>0</value>
     </param>
     <param>
-      <key>v_offset</key>
-      <value>0</value>
+      <key>y_per_div</key>
+      <value>10</value>
     </param>
     <param>
-      <key>t_scale</key>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
       <value>0</value>
     </param>
     <param>
-      <key>ac_couple</key>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
       <value>False</value>
     </param>
     <param>
-      <key>xy_mode</key>
+      <key>average</key>
       <value>False</value>
     </param>
     <param>
-      <key>num_inputs</key>
-      <value>1</value>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
     </param>
     <param>
       <key>win_size</key>
@@ -677,10 +639,357 @@
     </param>
     <param>
       <key>notebook</key>
-      <value>nb0,1</value>
+      <value>nb0,3</value>
     </param>
     <param>
-      <key>trig_mode</key>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(320, 667)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate/decimation</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,3</value>
+    </param>
+    <param>
+      <key>trig_mode</key>
+      <value>wxgui.TRIG_MODE_NORM</value>
+    </param>
+    <param>
+      <key>y_axis_label</key>
+      <value>Counts</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(320, 883)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>ha5kfu_execproc_xx</key>
+    <param>
+      <key>id</key>
+      <value>ha5kfu_execproc_xx_0_0_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>cc</value>
+    </param>
+    <param>
+      <key>commandline</key>
+      <value>"csdr decimating_shift_addition_cc %g %d"%(rate, decimation)</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(80, 835)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>ha5kfu_execproc_xx</key>
+    <param>
+      <key>id</key>
+      <value>ha5kfu_execproc_xx_0_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>cc</value>
+    </param>
+    <param>
+      <key>commandline</key>
+      <value>"csdr shift_table_cc %g 32768"%rate</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(824, 771)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0_1_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,2</value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1080, 691)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
+    <key>wxgui_scopesink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_scopesink2_0_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,1</value>
+    </param>
+    <param>
+      <key>trig_mode</key>
       <value>wxgui.TRIG_MODE_NORM</value>
     </param>
     <param>
@@ -697,7 +1006,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(952, 875)</value>
+      <value>(824, 571)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -705,10 +1014,10 @@
     </param>
   </block>
   <block>
-    <key>ha5kfu_execproc_xx</key>
+    <key>wxgui_fftsink2</key>
     <param>
       <key>id</key>
-      <value>ha5kfu_execproc_xx_0</value>
+      <value>wxgui_fftsink2_0_1</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -716,31 +1025,87 @@
     </param>
     <param>
       <key>type</key>
-      <value>cc</value>
+      <value>complex</value>
     </param>
     <param>
-      <key>commandline</key>
-      <value>csdr shift_math_cc -0.25</value>
+      <key>title</key>
+      <value>FFT Plot</value>
     </param>
     <param>
-      <key>alias</key>
-      <value></value>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
     </param>
     <param>
-      <key>affinity</key>
-      <value></value>
+      <key>baseband_freq</key>
+      <value>0</value>
     </param>
     <param>
-      <key>minoutbuf</key>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
       <value>0</value>
     </param>
     <param>
-      <key>maxoutbuf</key>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
       <value>0</value>
     </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,1</value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
     <param>
       <key>_coordinate</key>
-      <value>(496, 483)</value>
+      <value>(824, 355)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -748,10 +1113,10 @@
     </param>
   </block>
   <block>
-    <key>ha5kfu_execproc_xx</key>
+    <key>wxgui_scopesink2</key>
     <param>
       <key>id</key>
-      <value>ha5kfu_execproc_xx_0_0</value>
+      <value>wxgui_scopesink2_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -759,11 +1124,59 @@
     </param>
     <param>
       <key>type</key>
-      <value>cc</value>
+      <value>complex</value>
     </param>
     <param>
-      <key>commandline</key>
-      <value>csdr shift_addition_cc -0.25</value>
+      <key>title</key>
+      <value>Scope Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>v_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>v_offset</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>t_scale</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ac_couple</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>xy_mode</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>num_inputs</key>
+      <value>1</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,0</value>
+    </param>
+    <param>
+      <key>trig_mode</key>
+      <value>wxgui.TRIG_MODE_NORM</value>
+    </param>
+    <param>
+      <key>y_axis_label</key>
+      <value>Counts</value>
     </param>
     <param>
       <key>alias</key>
@@ -774,16 +1187,107 @@
       <value></value>
     </param>
     <param>
-      <key>minoutbuf</key>
+      <key>_coordinate</key>
+      <value>(824, 235)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
       <value>0</value>
     </param>
+  </block>
+  <block>
+    <key>wxgui_fftsink2</key>
+    <param>
+      <key>id</key>
+      <value>wxgui_fftsink2_0</value>
+    </param>
     <param>
-      <key>maxoutbuf</key>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>complex</value>
+    </param>
+    <param>
+      <key>title</key>
+      <value>FFT Plot</value>
+    </param>
+    <param>
+      <key>samp_rate</key>
+      <value>samp_rate</value>
+    </param>
+    <param>
+      <key>baseband_freq</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>y_per_div</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>y_divs</key>
+      <value>10</value>
+    </param>
+    <param>
+      <key>ref_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>ref_scale</key>
+      <value>2.0</value>
+    </param>
+    <param>
+      <key>fft_size</key>
+      <value>1024</value>
+    </param>
+    <param>
+      <key>fft_rate</key>
+      <value>15</value>
+    </param>
+    <param>
+      <key>peak_hold</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>average</key>
+      <value>False</value>
+    </param>
+    <param>
+      <key>avg_alpha</key>
       <value>0</value>
     </param>
+    <param>
+      <key>win</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>win_size</key>
+      <value></value>
+    </param>
+    <param>
+      <key>grid_pos</key>
+      <value></value>
+    </param>
+    <param>
+      <key>notebook</key>
+      <value>nb0,0</value>
+    </param>
+    <param>
+      <key>freqvar</key>
+      <value>None</value>
+    </param>
+    <param>
+      <key>alias</key>
+      <value></value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
     <param>
       <key>_coordinate</key>
-      <value>(504, 635)</value>
+      <value>(824, 19)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -838,4 +1342,40 @@
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
+  <connection>
+    <source_block_id>blocks_throttle_0</source_block_id>
+    <sink_block_id>ha5kfu_execproc_xx_0_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>blocks_throttle_0</source_block_id>
+    <sink_block_id>ha5kfu_execproc_xx_0_0_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0_0_0_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0_0_0_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0_1_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0_0_0</source_block_id>
+    <sink_block_id>wxgui_fftsink2_0_1_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
+  <connection>
+    <source_block_id>ha5kfu_execproc_xx_0_0_0</source_block_id>
+    <sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
 </flow_graph>
diff --git a/ima_adpcm.c b/ima_adpcm.c
new file mode 100644
index 0000000000000000000000000000000000000000..03a9b7c579b1eb5e0428fac99ef0a1a582740686
--- /dev/null
+++ b/ima_adpcm.c
@@ -0,0 +1,176 @@
+/*
+
+This software is part of libcsdr, a set of simple DSP routines for 
+Software Defined Radio.
+
+Copyright (c) 2015, Andras Retzler <randras@sdr.hu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the name of the copyright holder nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+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 ANDRAS RETZLER 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.
+
+   Copyright 1997 Tim Kientzle.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+      This product includes software developed by Tim Kientzle
+      and published in ``The Programmer's Guide to Sound.''
+4. Neither the names of Tim Kientzle nor Addison-Wesley
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``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 TIM KIENTZLE OR ADDISON-WESLEY 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.
+*/
+
+/***********************************************************
+Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
+Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#ifdef USE_IMA_ADPCM
+
+#include "ima_adpcm.h"
+ 
+const int indexAdjustTable[16] = {
+   -1, -1, -1, -1,  // +0 - +3, decrease the step size
+    2, 4, 6, 8,     // +4 - +7, increase the step size
+   -1, -1, -1, -1,  // -0 - -3, decrease the step size
+    2, 4, 6, 8,     // -4 - -7, increase the step size
+};
+
+const int _stepSizeTable[89] = {
+   7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34,
+   37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
+   157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494,
+   544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
+   1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
+   4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
+   11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,
+   27086, 29794, 32767
+};
+
+static inline short ImaAdpcmDecode(unsigned char deltaCode, ima_adpcm_state_t* state) {
+   // Get the current step size
+   int step = _stepSizeTable[state->index];
+
+   // Construct the difference by scaling the current step size
+   // This is approximately: difference = (deltaCode+.5)*step/4
+   int difference = step>>3;
+   if ( deltaCode & 1 ) difference += step>>2;
+   if ( deltaCode & 2 ) difference += step>>1;
+   if ( deltaCode & 4 ) difference += step;
+   if ( deltaCode & 8 ) difference = -difference;
+
+   // Build the new sample
+   state->previousValue += difference;
+   if (state->previousValue > 32767) state->previousValue = 32767;
+   else if (state->previousValue < -32768) state->previousValue = -32768;
+
+   // Update the step for the next sample
+   state->index += indexAdjustTable[deltaCode];
+   if (state->index < 0) state->index = 0;
+   else if (state->index > 88) state->index = 88;
+
+   return state->previousValue;
+}
+
+static inline unsigned char ImaAdpcmEncode(short sample, ima_adpcm_state_t* state) {
+   int diff = sample - state->previousValue;
+   int step = _stepSizeTable[state->index];
+   int deltaCode = 0;
+
+   // Set sign bit
+   if (diff < 0) { deltaCode = 8; diff = -diff; }
+
+   // This is essentially deltaCode = (diff<<2)/step,
+   // except the roundoff is handled differently.
+   if ( diff >= step ) {  deltaCode |= 4;  diff -= step;  }
+   step >>= 1;
+   if ( diff >= step ) {  deltaCode |= 2;  diff -= step;  }
+   step >>= 1;
+   if ( diff >= step ) {  deltaCode |= 1;  diff -= step;  }
+
+   ImaAdpcmDecode(deltaCode,state);  // update state
+   return deltaCode;
+}
+
+ima_adpcm_state_t encode_ima_adpcm_i16_u8(short* input, unsigned char* output, int input_length, ima_adpcm_state_t state)
+{
+	int k=0;
+	for(int i=0;i<input_length/2;i++) 
+	{
+		output[k]=ImaAdpcmEncode(input[2*i],&state);
+		output[k++]|=ImaAdpcmEncode(input[2*i+1],&state)<<4;
+	}
+	return state;
+}
+
+ima_adpcm_state_t decode_ima_adpcm_u8_i16(unsigned char* input, short* output, int input_length, ima_adpcm_state_t state)
+{
+	int k=0;
+	for(int i=0;i<input_length;i++) 
+	{
+		output[k++]=ImaAdpcmDecode(input[i]&0xf,&state);
+		output[k++]=ImaAdpcmDecode( (input[i]>>4)&0xf,&state);
+	}
+	return state;
+}
+
+#endif
diff --git a/ima_adpcm.h b/ima_adpcm.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e7bd9d726bc65c096b6873b78c8e878500dc944
--- /dev/null
+++ b/ima_adpcm.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef USE_IMA_ADPCM
+
+typedef struct ImaState {
+   int index;    // Index into step size table
+   int previousValue; // Most recent sample value
+} ima_adpcm_state_t;
+
+ima_adpcm_state_t encode_ima_adpcm_i16_u8(short* input, unsigned char* output, int input_length, ima_adpcm_state_t state);
+ima_adpcm_state_t decode_ima_adpcm_u8_i16(unsigned char* input, short* output, int input_length, ima_adpcm_state_t state);
+
+#endif
diff --git a/libcsdr.c b/libcsdr.c
index 7d6e449e4103fbecb687dccc608f9df97d9ea74b..2cf5e9b913e7483acdf37f8b1499b92c25f6b762 100644
--- a/libcsdr.c
+++ b/libcsdr.c
@@ -205,6 +205,64 @@ float shift_math_cc(complexf *input, complexf* output, int input_size, float rat
 	return phase;
 }
 
+
+
+shift_table_data_t shift_table_init(int table_size)
+{
+	//RTODO
+	shift_table_data_t output;
+	output.table=(float*)malloc(sizeof(float)*table_size);
+	output.table_size=table_size;
+	for(int i=0;i<table_size;i++)
+	{
+		output.table[i]=sin(((float)i/table_size)*(PI/2));
+	}
+	return output;
+}
+
+void shift_table_deinit(shift_table_data_t table_data)
+{
+	free(table_data.table);
+}
+
+float shift_table_cc(complexf* input, complexf* output, int input_size, float rate, shift_table_data_t table_data, float starting_phase)
+{
+	//RTODO
+	rate*=2;
+	//Shifts the complex spectrum. Basically a complex mixer. This version uses a pre-built sine table.
+	float phase=starting_phase;
+	float phase_increment=rate*PI;
+	float cosval, sinval;
+	for(int i=0;i<input_size; i++) //@shift_math_cc
+	{
+		int sin_index, cos_index, temp_index, sin_sign, cos_sign;
+		//float vphase=fmodf(phase,PI/2); //between 0 and 90deg
+		int quadrant=phase/(PI/2); //between 0 and 3
+		float vphase=phase-quadrant*(PI/2);
+		sin_index=(vphase/(PI/2))*table_data.table_size; 
+		cos_index=table_data.table_size-1-sin_index;
+		if(quadrant&1) //in quadrant 1 and 3
+		{
+			temp_index=sin_index;
+			sin_index=cos_index;
+			cos_index=temp_index;
+		}
+		sin_sign=(quadrant>1)?-1:1; //in quadrant 2 and 3
+		cos_sign=(quadrant&&quadrant<3)?-1:1; //in quadrant 1 and 2
+		sinval=sin_sign*table_data.table[sin_index];
+		cosval=cos_sign*table_data.table[cos_index];
+		//we multiply two complex numbers.
+		//how? enter this to maxima (software) for explanation:
+		//   (a+b*%i)*(c+d*%i), rectform;
+		iof(output,i)=cosval*iof(input,i)-sinval*qof(input,i);
+		qof(output,i)=sinval*iof(input,i)+cosval*qof(input,i);
+		phase+=phase_increment;
+		while(phase>2*PI) phase-=2*PI; //@shift_math_cc: normalize phase
+		while(phase<0) phase+=2*PI;
+	}
+	return phase;
+}
+
 int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decimation, float *taps, int taps_length)
 {
 	//Theory: http://www.dspguru.com/dsp/faqs/multirate/decimation
@@ -339,6 +397,8 @@ fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, i
 
 void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size)
 {
+	//use the overlap & add method for filtering
+
 	//calculate FFT on input buffer
 	fft_execute(plan);
 
@@ -593,6 +653,14 @@ complexf fmdemod_quadri_cf(complexf* input, float* output, int input_size, float
 	return input[input_size-1];
 }
 
+inline int is_nan(float f) 
+{
+	//http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c
+    unsigned u = *(unsigned*)&f;
+    return (u&0x7F800000) == 0x7F800000 && (u&0x7FFFFF); // Both NaN and qNan.
+}
+
+
 float deemphasis_wfm_ff (float* input, float* output, int input_size, float tau, int sample_rate, float last_output)
 {
 	/* 
@@ -604,6 +672,7 @@ float deemphasis_wfm_ff (float* input, float* output, int input_size, float tau,
 	*/
 	float dt = 1.0/sample_rate;
 	float alpha = dt/(tau+dt);
+	if(is_nan(last_output)) last_output=0.0; //if last_output is NaN
 	output[0]=alpha*input[0]+(1-alpha)*last_output; 
 	for (int i=1;i<input_size;i++) //@deemphasis_wfm_ff
        output[i]=alpha*input[i]+(1-alpha)*output[i-1]; //this is the simplest IIR LPF
@@ -628,6 +697,7 @@ int deemphasis_nfm_ff (float* input, float* output, int input_size, int sample_r
 	DNFMFF_ADD_ARRAY(48000)
 	DNFMFF_ADD_ARRAY(44100)
 	DNFMFF_ADD_ARRAY(8000)
+	DNFMFF_ADD_ARRAY(11025)
 
 	if(!taps_length) return 0; //sample rate n
 	int i;
diff --git a/libcsdr.h b/libcsdr.h
index a66d72b19377848fc0f3b5e6c85368a1cf402d22..99774028fc057a12feaec4db063e84ad83f1ed04 100644
--- a/libcsdr.h
+++ b/libcsdr.h
@@ -97,6 +97,7 @@ void amdemod_estimator_cf(complexf* input, float *output, int input_size, float
 void limit_ff(float* input, float* output, int input_size, float max_amplitude);
 
 //filters, decimators, resamplers, shift, etc.
+float fir_one_pass_ff(float* input, float* taps, int taps_length);
 int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decimation, float *taps, int taps_length);
 int deemphasis_nfm_ff (float* input, float* output, int input_size, int sample_rate);
 float deemphasis_wfm_ff (float* input, float* output, int input_size, float tau, int sample_rate, float last_output);
@@ -146,6 +147,16 @@ typedef struct fractional_decimator_ff_s
 } fractional_decimator_ff_t;
 fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, fractional_decimator_ff_t d);
 
+typedef struct shift_table_data_s
+{
+	float* table;
+	int table_size;	
+} shift_table_data_t;
+void shift_table_deinit(shift_table_data_t table_data);
+shift_table_data_t shift_table_init(int table_size);
+float shift_table_cc(complexf* input, complexf* output, int input_size, float rate, shift_table_data_t table_data, float starting_phase);
+
+
 int log2n(int x);
 int next_pow2(int x);
 void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size);
@@ -156,6 +167,4 @@ void convert_f_u8(float* input, unsigned char* output, int input_size);
 void convert_f_i16(float* input, short* output, int input_size);
 void convert_i16_f(short* input, float* output, int input_size);
 
-
-
-
+int is_nan(float f);
diff --git a/libcsdr_gpl.c b/libcsdr_gpl.c
index 7798ae91acfe119b662be7eb8ae44434b2c1ae89..c17390daf97a6b8e5b63ab3c6deb1167f04a49ed 100644
--- a/libcsdr_gpl.c
+++ b/libcsdr_gpl.c
@@ -96,6 +96,43 @@ void shift_addition_cc_test(shift_addition_data_t d)
 	printf("]; error_vector_db=20*log10(error_vector); plot(error_vector_db);\n");
 }
 
+shift_addition_data_t decimating_shift_addition_init(float rate, int decimation)
+{
+	return shift_addition_init(rate*decimation);
+}
+
+decimating_shift_addition_status_t decimating_shift_addition_cc(complexf *input, complexf* output, int input_size, shift_addition_data_t d, int decimation, decimating_shift_addition_status_t s)
+{
+	//The original idea was taken from wdsp:
+	//http://svn.tapr.org/repos_sdr_hpsdr/trunk/W5WC/PowerSDR_HPSDR_mRX_PS/Source/wdsp/shift.c
+	//However, this method introduces noise (from floating point rounding errors), which increases until the end of the buffer.
+	//fprintf(stderr, "cosd=%g sind=%g\n", d.cosdelta, d.sindelta);
+	float cosphi=cos(s.starting_phase);
+	float sinphi=sin(s.starting_phase);
+	float cosphi_last, sinphi_last;
+	int i;
+	int k=0;
+	for(i=s.decimation_remain;i<input_size;i+=decimation) //@shift_addition_cc: work
+	{
+		iof(output,k)=cosphi*iof(input,i)-sinphi*qof(input,i);
+		qof(output,k)=sinphi*iof(input,i)+cosphi*qof(input,i);
+		k++;
+		//using the trigonometric addition formulas
+		//cos(phi+delta)=cos(phi)cos(delta)-sin(phi)*sin(delta)
+		cosphi_last=cosphi;
+		sinphi_last=sinphi;
+		cosphi=cosphi_last*d.cosdelta-sinphi_last*d.sindelta;
+		sinphi=sinphi_last*d.cosdelta+cosphi_last*d.sindelta;
+	}
+	s.decimation_remain=i-input_size;
+	s.starting_phase+=d.rate*PI*k;
+	s.output_size=k;
+	while(s.starting_phase>PI) s.starting_phase-=2*PI; //@shift_addition_cc: normalize starting_phase
+	while(s.starting_phase<-PI) s.starting_phase+=2*PI; 
+	return s;
+}
+
+
 float agc_ff(float* input, float* output, int input_size, float reference, float attack_rate, float decay_rate, float max_gain, short hang_time, short attack_wait_time, float gain_filter_alpha, float last_gain)
 {
 	/*
diff --git a/libcsdr_gpl.h b/libcsdr_gpl.h
index 98c0febbb0a7cd1b6b6d74e8941b0db0b68585a5..a4bfd230800940c6d6b58a0237938a7a615ed984 100644
--- a/libcsdr_gpl.h
+++ b/libcsdr_gpl.h
@@ -35,5 +35,14 @@ void shift_addition_cc_test(shift_addition_data_t d);
 
 float agc_ff(float* input, float* output, int input_size, float reference, float attack_rate, float decay_rate, float max_gain, short hang_time, short attack_wait_time, float gain_filter_alpha, float last_gain);
 
+typedef struct decimating_shift_addition_status_s
+{
+	int decimation_remain;
+	float starting_phase;
+	int output_size;
+} decimating_shift_addition_status_t;
+decimating_shift_addition_status_t decimating_shift_addition_cc(complexf *input, complexf* output, int input_size, shift_addition_data_t d, int decimation, decimating_shift_addition_status_t s);
+shift_addition_data_t decimating_shift_addition_init(float rate, int decimation);
+
 #endif
 
diff --git a/libcsdr_wrapper.c b/libcsdr_wrapper.c
index 4ab53e3f0c35ae3c76eab98b755fa0c5adcd586d..3e6ab8772181395e3bbff123e8d78d3c19081c26 100644
--- a/libcsdr_wrapper.c
+++ b/libcsdr_wrapper.c
@@ -1,3 +1,4 @@
 #include "libcsdr.c"
 #include "libcsdr_gpl.c"
+#include "ima_adpcm.c"
 //this wrapper helps parsevect.py to generate better output
diff --git a/predefined.h b/predefined.h
index e0c74bbe9948a914b8757461df3e2498a829d917..a00607f33a20d5195a0d63628fc24e8b38ad400b 100644
--- a/predefined.h
+++ b/predefined.h
@@ -50,11 +50,9 @@ function mkdeemph(sr,tapnum,norm_freq)
 	printf("%g, ",coeffs);
 	printf("\n")
 end 
-
-mkdeemph(48000,199,500)
-	
 */
 
+//mkdeemph(48000,199,500)
 float deemphasis_nfm_predefined_fir_48000[] = 
 { 0.00172568, 0.00179665, 0.00191952, 0.00205318, 0.00215178, 0.00217534, 0.00209924, 0.00192026, 0.00165789, 0.0013502, 0.00104545, 0.000790927, 0.000621911, 0.000553077, 0.000574554, 0.000653624, 0.000741816, 0.000785877, 0.000740151, 0.000577506, 0.000296217, -7.89273e-05, -0.0005017, -0.000914683, -0.00126243, -0.00150456, -0.00162564, -0.0016396, -0.00158725, -0.00152751, -0.00152401, -0.00163025, -0.00187658, -0.00226223, -0.00275443, -0.003295, -0.0038132, -0.00424193, -0.00453375, -0.00467274, -0.00467943, -0.00460728, -0.00453119, -0.00453056, -0.00467051, -0.00498574, -0.00547096, -0.00608027, -0.00673627, -0.00734698, -0.00782705, -0.00811841, -0.00820539, -0.00812057, -0.00793936, -0.00776415, -0.00770111, -0.00783479, -0.00820643, -0.00880131, -0.00954878, -0.0103356, -0.0110303, -0.011514, -0.0117094, -0.0116029, -0.0112526, -0.0107795, -0.010343, -0.0101053, -0.0101917, -0.0106561, -0.0114608, -0.0124761, -0.0135018, -0.0143081, -0.0146885, -0.0145126, -0.0137683, -0.0125796, -0.0111959, -0.00994914, -0.00918404, -0.00917447, -0.0100402, -0.0116822, -0.0137533, -0.0156723, -0.0166881, -0.0159848, -0.0128153, -0.00664117, 0.00274383, 0.0151313, 0.0298729, 0.0459219, 0.0619393, 0.076451, 0.0880348, 0.0955087, 0.098091, 0.0955087, 0.0880348, 0.076451, 0.0619393, 0.0459219, 0.0298729, 0.0151313, 0.00274383, -0.00664117, -0.0128153, -0.0159848, -0.0166881, -0.0156723, -0.0137533, -0.0116822, -0.0100402, -0.00917447, -0.00918404, -0.00994914, -0.0111959, -0.0125796, -0.0137683, -0.0145126, -0.0146885, -0.0143081, -0.0135018, -0.0124761, -0.0114608, -0.0106561, -0.0101917, -0.0101053, -0.010343, -0.0107795, -0.0112526, -0.0116029, -0.0117094, -0.011514, -0.0110303, -0.0103356, -0.00954878, -0.00880131, -0.00820643, -0.00783479, -0.00770111, -0.00776415, -0.00793936, -0.00812057, -0.00820539, -0.00811841, -0.00782705, -0.00734698, -0.00673627, -0.00608027, -0.00547096, -0.00498574, -0.00467051, -0.00453056, -0.00453119, -0.00460728, -0.00467943, -0.00467274, -0.00453375, -0.00424193, -0.0038132, -0.003295, -0.00275443, -0.00226223, -0.00187658, -0.00163025, -0.00152401, -0.00152751, -0.00158725, -0.0016396, -0.00162564, -0.00150456, -0.00126243, -0.000914683, -0.0005017, -7.89273e-05, 0.000296217, 0.000577506, 0.000740151, 0.000785877, 0.000741816, 0.000653624, 0.000574554, 0.000553077, 0.000621911, 0.000790927, 0.00104545, 0.0013502, 0.00165789, 0.00192026, 0.00209924, 0.00217534, 0.00215178, 0.00205318, 0.00191952, 0.00179665, 0.00172568 };
 
@@ -64,3 +62,7 @@ float deemphasis_nfm_predefined_fir_8000[] =
 
 float deemphasis_nfm_predefined_fir_44100[] = 
 { 0.0025158, 0.00308564, 0.00365507, 0.00413598, 0.00446279, 0.00461162, 0.00460866, 0.00452474, 0.00445739, 0.00450444, 0.00473648, 0.0051757, 0.0057872, 0.00648603, 0.00715856, 0.00769296, 0.00801081, 0.00809096, 0.00797853, 0.00777577, 0.00761627, 0.00762871, 0.00789987, 0.00844699, 0.00920814, 0.0100543, 0.0108212, 0.0113537, 0.011551, 0.0113994, 0.0109834, 0.0104698, 0.0100665, 0.00996618, 0.0102884, 0.0110369, 0.0120856, 0.0131998, 0.0140907, 0.0144924, 0.0142417, 0.0133401, 0.0119771, 0.0105043, 0.00935909, 0.00895022, 0.00952985, 0.0110812, 0.0132522, 0.015359, 0.0164664, 0.0155409, 0.0116496, 0.00416925, -0.00703664, -0.021514, -0.0382135, -0.0555955, -0.0718318, -0.0850729, -0.0937334, -0.0967458, -0.0937334, -0.0850729, -0.0718318, -0.0555955, -0.0382135, -0.021514, -0.00703664, 0.00416925, 0.0116496, 0.0155409, 0.0164664, 0.015359, 0.0132522, 0.0110812, 0.00952985, 0.00895022, 0.00935909, 0.0105043, 0.0119771, 0.0133401, 0.0142417, 0.0144924, 0.0140907, 0.0131998, 0.0120856, 0.0110369, 0.0102884, 0.00996618, 0.0100665, 0.0104698, 0.0109834, 0.0113994, 0.011551, 0.0113537, 0.0108212, 0.0100543, 0.00920814, 0.00844699, 0.00789987, 0.00762871, 0.00761627, 0.00777577, 0.00797853, 0.00809096, 0.00801081, 0.00769296, 0.00715856, 0.00648603, 0.0057872, 0.0051757, 0.00473648, 0.00450444, 0.00445739, 0.00452474, 0.00460866, 0.00461162, 0.00446279, 0.00413598, 0.00365507, 0.00308564, 0.0025158 };
+
+//mkdeemph(11025,79,500)
+float deemphasis_nfm_predefined_fir_11025[] =
+{ 0.00113162, 0.000911207, 0.00173815, -0.000341385, -0.000849373, -0.00033066, -0.00290692, -0.00357326, -0.0031917, -0.00607078, -0.00659201, -0.00601551, -0.00886603, -0.00880243, -0.00759841, -0.0100344, -0.0088993, -0.00664423, -0.00835258, -0.00572919, -0.00214109, -0.00302443, 0.00132902, 0.00627003, 0.00596494, 0.0120731, 0.0180437, 0.0176243, 0.0253776, 0.0316572, 0.0298485, 0.0393389, 0.0446019, 0.0389943, 0.0516463, 0.0521951, 0.0350192, 0.0600945, 0.0163128, -0.217526, -0.378533, -0.217526, 0.0163128, 0.0600945, 0.0350192, 0.0521951, 0.0516463, 0.0389943, 0.0446019, 0.0393389, 0.0298485, 0.0316572, 0.0253776, 0.0176243, 0.0180437, 0.0120731, 0.00596494, 0.00627003, 0.00132902, -0.00302443, -0.00214109, -0.00572919, -0.00835258, -0.00664423, -0.0088993, -0.0100344, -0.00759841, -0.00880243, -0.00886603, -0.00601551, -0.00659201, -0.00607078, -0.0031917, -0.00357326, -0.00290692, -0.00033066, -0.000849373, -0.000341385, 0.00173815, 0.000911207, 0.00113162 };
diff --git a/sdr.js/exported_functions.py b/sdr.js/exported_functions.py
new file mode 100644
index 0000000000000000000000000000000000000000..28b0021a19e915c60b9c7fe500290535ddc714ed
--- /dev/null
+++ b/sdr.js/exported_functions.py
@@ -0,0 +1,81 @@
+"""
+This software is part of libcsdr, a set of simple DSP routines for 
+Software Defined Radio.
+
+Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the name of the copyright holder nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+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 ANDRAS RETZLER 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.
+"""
+
+
+exported_functions= \
+"""firdes_lowpass_f
+firdes_bandpass_c
+firdes_wkernel_blackman
+firdes_wkernel_hamming
+firdes_wkernel_boxcar
+firdes_get_window_from_string
+firdes_get_string_from_window
+firdes_filter_len
+fmdemod_quadri_cf
+fmdemod_quadri_novect_cf
+fmdemod_atan_cf
+amdemod_cf
+amdemod_estimator_cf
+limit_ff
+fir_decimate_cc
+deemphasis_nfm_ff
+deemphasis_wfm_ff
+shift_math_cc
+dcblock_ff
+fastdcblock_ff
+fastagc_ff
+rational_resampler_ff
+rational_resampler_get_lowpass_f
+apply_window_c
+apply_window_f
+logpower_cf
+fractional_decimator_ff
+shift_table_deinit
+shift_table_init
+shift_table_cc
+log2n
+next_pow2
+apply_fir_fft_cc
+gain_ff
+convert_u8_f
+convert_f_u8
+convert_f_i16
+convert_i16_f
+shift_addition_init
+shift_addition_cc
+shift_addition_cc_test
+agc_ff
+decimating_shift_addition_cc
+decimating_shift_addition_init
+encode_ima_adpcm_i16_u8
+decode_ima_adpcm_u8_i16"""
+
+exported_functions_quoted=map(lambda x:"'_"+x+"'",exported_functions.split("\n"))
+print "["+(", ".join(exported_functions_quoted))+"]"
diff --git a/sdr.js/sdrjs-footer.js b/sdr.js/sdrjs-footer.js
new file mode 100644
index 0000000000000000000000000000000000000000..21ea9925e9ce1e125601ee311f608980f782172f
--- /dev/null
+++ b/sdr.js/sdrjs-footer.js
@@ -0,0 +1,296 @@
+// ========================================================== 
+// ========= / THE CODE COMPILED BY EMCC ENDS HERE ==========
+// ========================================================== 
+
+asm$ =
+{
+	malloc: function(type, size) 
+	{
+		real_size=size*type.BYTES_PER_ELEMENT;
+		pointer = Module._malloc(real_size);
+		heap = new Uint8Array(Module.HEAPU8.buffer, pointer, real_size);
+		return {
+			asm$: true,
+			ptr: heap.byteOffset,
+			free: function() { Module._free(this.ptr); },
+			arr: new type(heap.buffer, heap.byteOffset, size),
+			size: size
+		};
+	},
+	cpy: function(dst, dst_offset, src, src_offset, size) 
+	{
+		if(typeof dst.asm$!='undefined') dst=dst.arr;
+		if(typeof src.asm$!='undefined') src=src.arr;
+		for(var i=0;i<size;i++) 
+			dst[dst_offset+i]=src[src_offset+i];
+	}
+};
+
+//                                                  void firdes_lowpass_f(float *output, int length, float cutoff_rate, window_t window)
+firdes_lowpass_f = Module.cwrap('firdes_lowpass_f', null,                 ['number',     'number',   'number',          'number']);
+
+//                                                            rational_resampler_ff_t rational_resampler_ff(float *input, float *output, int input_size, int interpolation, int decimation, float *taps, int taps_length, int last_taps_delay)
+rational_resampler_ff = Module.cwrap('rational_resampler_ff', 'struct',                                    ['number',     'number',      'number',       'number',          'number',       'number',    'number',        'number']);
+
+
+rational_resampler_ff=function(pinput,poutput,input_length,interpolation,decimation,ptaps,taps_length,last_taps_delay )
+{	stackbase=STACKTOP;
+	STACKTOP+=4*3;
+	_rational_resampler_ff(stackbase, pinput, poutput, input_length, interpolation, decimation, ptaps, taps_length,last_taps_delay);
+	returnstruct={ input_processed: getValue(stackbase,'i32'), output_size: getValue(stackbase+4,'i32'), last_taps_delay: getValue(stackbase+8,'i32') };
+	STACKTOP=stackbase;
+	return returnstruct;
+}
+
+sdrjs={};
+
+sdrjs.WINDOW_BOXCAR=0;
+sdrjs.WINDOW_BLACKMAN=1;
+sdrjs.WINDOW_HAMMING=2;
+
+//this will be impportant whil converting arrays
+//http://stackoverflow.com/questions/25839216/convert-float32array-to-int16array
+
+/*sdrjs.prototype.FirdesLowpassF=function(taps_length,transition_bw,window)
+{
+	this.calculate=function(){}
+	this.get_output=function(){}
+	this.get_output_heap=function(){}
+};*/
+
+
+sdrjs.ConvertI16_F=function(i16data)
+{
+	var f32data=new Float32Array(i16data.length);
+	for(var i=0;i<i16data.length;i++) f32data[i]=i16data[i]/32768;
+	return f32data;
+}
+
+ima_adpcm_codec=function(encode,pinput,poutput,input_length,state)
+{
+	myfunc=(encode)?_encode_ima_adpcm_i16_u8:_decode_ima_adpcm_u8_i16;
+	stackbase=STACKTOP;
+	STACKTOP+=4*2; //sizeof(int)*2
+	myfunc(stackbase, pinput, poutput, input_length, state.ptr);
+	state.arr[0]=getValue(stackbase+0,'i32');
+	state.arr[1]=getValue(stackbase+4,'i32');
+	STACKTOP=stackbase;
+};
+
+sdrjs.ImaAdpcm=function()
+{
+	this.BUFSIZE=1024*64;
+	this.ima_adpcm_state=asm$.malloc(Int32Array,2);
+	this.i16_buffer=asm$.malloc(Int16Array,this.BUFSIZE*2);
+	this.u8_buffer=asm$.malloc(Uint8Array,this.BUFSIZE);
+	this.ima_adpcm_state.arr[0]=0;
+	this.ima_adpcm_state.arr[1]=0;
+
+	this.encode=function(data)
+	{
+		//not_tested_yet
+		asm$.cpy(this.i16_buffer.arr,0,data,0,data.length);
+		ima_adpcm_codec(true,this.i16_buffer.ptr,this.u8_buffer.ptr,data.length,this.ima_adpcm_state);		
+		out=new Uint8Array(data.length/2);
+		asm$.cpy(out,0,this.u8_buffer,0,data.length/2);
+		return out;	
+	};
+
+	this.decode=function(data)
+	{
+		asm$.cpy(this.u8_buffer.arr,0,data,0,data.length);
+		ima_adpcm_codec(false,this.u8_buffer.ptr,this.i16_buffer.ptr,data.length,this.ima_adpcm_state);
+		out=new Int16Array(data.length*2);
+		asm$.cpy(out,0,this.i16_buffer.arr,0,data.length*2);
+		return out;	
+	};
+	this.reset=function() { this.ima_adpcm_state.arr[0]=this.ima_adpcm_state.arr[1]=0|0; }
+};
+
+sdrjs.REBUFFER_FIXED=0; //rebuffer should return arrays of fixed size
+sdrjs.REBUFFER_MAX=1;	//rebuffer should return arrays with a maximal size of the parameter size
+
+sdrjs.Rebuffer=function(size,mode)
+{
+	this.mode=mode;
+	this.size=size;
+	this.total_size=0;
+	this.arrays=[];
+	this.last_arr=[];
+	this.last_arr_offset=0;
+	this.push=function(data)
+	{
+		this.total_size+=data.length;
+		this.arrays.push(data);
+	};
+	this.remaining=function() 
+	{ 
+		var fixed_bufs_num=Math.floor(this.total_size/this.size);
+		if(!this.mode) return fixed_bufs_num;
+		else return fixed_bufs_num+(!!(this.total_size-fixed_bufs_num*this.size)); //if REBUFFER_MAX, add one if we could return one more buffer (smaller than the fixed size)
+	};
+	this.take=function() { var a=this._take(); /*console.log(a);*/ return a; };
+	this._take=function() 
+	{
+		var remain=this.size;
+		var offset=0;
+		var obuf=new Float32Array(size);
+		//console.log("==== get new obuf ====", size);
+		while(remain)
+		{
+			if(this.last_arr_offset==this.last_arr.length)
+			{
+				if(this.arrays.length==0)
+				{ 
+					//console.log("this should not happen");
+					if(this.mode) //REBUFFER_MAX
+					{
+						this.total_size=0;
+						return obuf.subarray(0,offset);  
+					}
+					else return new Float32Array(0); //REBUFFER_FIXED
+				}
+				//console.log("pick new last_arr");
+				this.last_arr=this.arrays.shift();
+				this.last_arr_offset=0;
+			}
+			var rwithin=this.last_arr.length-this.last_arr_offset;
+			//console.log("b :: ","remain", remain, "rwithin",rwithin,"last_arr.length",this.last_arr.length,"larroffset",this.last_arr_offset,"offset",offset);
+			if(remain<rwithin)
+			{
+				//console.log("remain < rwithin"); //seems problematic @Andris
+				for(var i=0;i<remain;i++) obuf[offset++]=this.last_arr[this.last_arr_offset++];
+				remain=0;
+			}
+			else
+			{
+				//console.log("remain > rwithin");
+				for(var i=0;i<rwithin;i++) obuf[offset++]=this.last_arr[this.last_arr_offset++];
+				remain-=rwithin;
+			}
+			//console.log("e :: ","remain", remain, "rwithin",rwithin,"last_arr.length",this.last_arr.length,"larroffset",this.last_arr_offset,"offset",offset);
+		}
+			
+		this.total_size-=obuf.length;
+		//console.log("return _take");
+		return obuf;
+	};
+};
+
+sdrjs.RationalResamplerFF=function(interpolation,decimation,transition_bw,window)
+{
+	this.interpolation=interpolation;
+	this.decimation=decimation;
+	this.transition_bw = (typeof transition_bw=='undefined')?0.05:transition_bw;
+	this.window = (typeof window=='undefined')?1:window;
+	this.buffer_size=1024*512;
+	this.output_buffer_size=Math.floor((this.buffer_size*interpolation)/decimation);
+	this.input_buffer = asm$.malloc(Float32Array,this.buffer_size);
+	this.output_buffer = asm$.malloc(Float32Array,this.output_buffer_size);
+	//Calculate filter
+	this.taps_length = Math.floor(4/this.transition_bw);
+	this.taps = asm$.malloc(Float32Array,this.taps_length);
+	var cutoff_for_interpolation=1.0/interpolation;
+	var cutoff_for_decimation=1.0/decimation;
+	var cutoff = (cutoff_for_interpolation<cutoff_for_decimation)?cutoff_for_interpolation:cutoff_for_decimation; //get the lower
+	firdes_lowpass_f(this.taps.ptr, this.taps_length, cutoff/2, window);
+	
+	this.remain = 0;
+	this.remain_offset=0;
+	this.last_taps_delay=0;
+
+	this.process=function(input)
+	{
+		
+		if(input.length+this.remain > this.buffer_size)
+		{
+			return new Float32Array(0); console.log("sdrjs.RationalResamplerFF: critical audio buffering error"); //This should not happen...
+		/*	console.log("RationalResamplerFF: splitting..."); //TODO: this branch has not been checked
+			output_buffers=Array();
+			new_buffer_size=this.buffer_size/2;
+			i=0;
+			//process the input in chunks of new_buffer_size, and add the output product Float32Array-s to output_buffers.
+			while((i++)*new_buffer_size<=input.length)
+			{
+				output_buffers.push(this._process_noheapcheck(input.subarray(i*new_buffer_size,(i+1)*new_buffer_size)));
+			}
+			//add up the sizes of the output_buffer-s.
+			total_output_length=0;
+			output_buffers.forEach(function(a){total_output_length+=a.length;});
+			//create one big buffer from concatenating the output_buffer-s
+			output=new Float32Array(total_output_length);
+			output_pos=0;
+			output_buffers.forEach(function(a){
+				asm$.cpy(output,output_pos,a,0,a.length);
+				output_pos+=a.length;
+			});
+			return output;*/
+		}
+		else return this._process_noheapcheck(input);
+	};
+	this._process_noheapcheck=function(input) //if we are sure we have enough space in the buffers 
+	{
+		asm$.cpy(this.input_buffer.arr,0,this.input_buffer.arr,this.remain_offset,this.remain);
+		asm$.cpy(this.input_buffer.arr, this.remain, input, 0, input.length);
+		var total_input_size=input.length+this.remain;
+		d=rational_resampler_ff(this.input_buffer.ptr, this.output_buffer.ptr, total_input_size, this.interpolation, this.decimation, this.taps.ptr, this.taps_length, this.last_taps_delay);
+		this.last_taps_delay=d.last_taps_delay;
+		this.remain=total_input_size-d.input_processed;
+		this.remain_offset=d.input_processed;
+		var output_copy_arr=new Float32Array(d.output_size);
+		asm$.cpy(output_copy_arr,0,this.output_buffer.arr,0,d.output_size);
+		return output_copy_arr;
+	};
+};
+
+
+_sdrjs_logb=function(what) { document.body.innerHTML+=what+"<br />"; }
+
+
+function test_firdes_lowpass_f_original()
+{
+	//Original method explained over here: 
+	//http://kapadia.github.io/emscripten/2013/09/13/emscripten-pointers-and-pointers.html
+	_sdrjs_logb("test_firdes_lowpass_f_original():");
+	_sdrjs_logb("Now designing FIR filter with firdes_lowpass_f in sdr.js...");
+	_sdrjs_logb("output should be the same as: <strong>csdr firdes_lowpass_f 0.1 101 HAMMING</strong>");
+	
+	var outputSize = 101*4;
+	var outputPtr = Module._malloc(outputSize);
+	var outputHeap = new Uint8Array(Module.HEAPU8.buffer, outputPtr, outputSize);
+	firdes_lowpass_f(outputHeap.byteOffset,101,0.1,2);
+	var output = new Float32Array(outputHeap.buffer, outputHeap.byteOffset, 101);
+	outputStr=String();
+	for(i=0;i<output.length;i++) outputStr+=output[i].toFixed(6)+", ";
+	Module._free(outputHeap.byteOffset);
+	_sdrjs_logb(outputStr);
+}
+
+
+function test_firdes_lowpass_f_new()
+{
+	//This is much simpler, using asm$
+	_sdrjs_logb("test_firdes_lowpass_f_new():");
+	_sdrjs_logb("Now designing FIR filter with firdes_lowpass_f in sdr.js...");
+	_sdrjs_logb("output should be the same as: <strong>csdr firdes_lowpass_f 0.1 101 HAMMING</strong>");
+	
+	output=asm$.malloc(Float32Array,101);
+	firdes_lowpass_f(output.ptr,101,0.1,2);
+	outputStr=String();
+	for(i=0;i<output.arr.length;i++) outputStr+=(output.arr[i]).toFixed(6)+", ";
+	output.free();
+	_sdrjs_logb(outputStr);
+}
+
+function test_struct_return_value()
+{
+	v=STACKTOP;
+	STACKTOP+=4*3;
+	_shift_addition_init(v,0.2);
+	console.log( 
+		"sinval=", getValue(v,'float'), 
+		"cosval=", getValue(v+4,'float'), 
+		"rate=", getValue(v+8,'float') 
+	);
+	STACKTOP=v;
+}
diff --git a/sdr.js/sdrjs-header.js b/sdr.js/sdrjs-header.js
new file mode 100644
index 0000000000000000000000000000000000000000..f37e171608199b1a51155d746d9ad7fdfef90493
--- /dev/null
+++ b/sdr.js/sdrjs-header.js
@@ -0,0 +1,25 @@
+/*
+This file is part of libcsdr.
+
+	Copyright (c) Andras Retzler, HA7ILM <randras@sdr.hu>
+	Copyright (c) Warren Pratt, NR0V <warren@wpratt.com>
+	Copyright 2006,2010,2012 Free Software Foundation, Inc.
+
+    libcsdr is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    libcsdr is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libcsdr.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// ========================================================== 
+// ========= THE CODE COMPILED BY EMCC STARTS HERE: =========
+// ========================================================== 
+