private void fm_demodulate(double tune_freq, Int16[] dat, string wavefilename, TimeStampLog log) { Int32[] i_dat = new Int32[dat.Length]; Int32[] q_dat = new Int32[dat.Length]; int rem = (int)(tune_freq / SAMPLE_FREQ); tune_freq = tune_freq - SAMPLE_FREQ * rem; // TODO: correctly calculate frequency aliasing log.start(); mixer((int)tune_freq, dat, i_dat, q_dat); log.stop("mixer: "); log.start(); // 40MHz -> (CIC 1/32) -> 1.25MHz -> (FIR 2/5) -> 500kHz -> // (FIR 2/5 cutoff 80kHz:0.08) -> 200kHz -> (FIR 3/5 cutoff 48kHz:0.08) -> 120kHz -> (FIR 2/5 cutoff 15kHz:0.0625) -> 48kHz double[] i_cic = cic(i_dat, 3, 32); double[] q_cic = cic(q_dat, 3, 32); // 1.25MHz log.stop("cic: "); log.start(); double[] i_fir1 = fir(i_cic, 2, 5, fir_coef_255tap_008); // 500kHz (cutoff 200kHz) double[] q_fir1 = fir(q_cic, 2, 5, fir_coef_255tap_008); // FM demodulation double[] arctans = fm_demodulate_sub(i_fir1, q_fir1); double[] arctans2 = fir(arctans, 2, 5, fir_coef_255tap_008); // 200kHz (cutoff 80kHz) double[] arctans3 = fir(arctans2, 3, 5, fir_coef_255tap_008); // 120kHz (cutoff 48kHz) double[] arctans4 = fir(arctans3, 2, 5, fir_coef_255tap_0625); // 48kHz (cutoff 15kHz) double[] arctans5 = de_emphasis(arctans4, 0.67523190665); // fc = 3kHz/48kHz = 0.0625, e^(-2pi*0.0625) log.stop("FIR: "); FileStream fs = new FileStream(wavefilename, FileMode.CreateNew); BinaryWriter bw = new BinaryWriter(fs, Encoding.ASCII); write_wave_header(bw, (uint)arctans5.Length * 2); double maxAmp = 0.0; for (var i = 0; i < arctans5.Length; i++) { double val = Math.Abs(arctans5[i]); if (maxAmp < val) { maxAmp = val; } } for (var i = 0; i < arctans5.Length; i++) { double v = arctans5[i]; short val = (short)((v / maxAmp) * (1 << 15) + (1 << 14)); bw.Write(val); } bw.Close(); fs.Close(); }
private void fm_demodulate2(Int32[] dat, string wavefilename, TimeStampLog log) { double[] arctans = new double[dat.Length]; for (var i = 0; i < dat.Length; i++) { arctans[i] = (double)dat[i] / (double)(1 << 29); // 48kHz (cutoff 15kHz) } log.start(); double[] arctans5 = arctans; // double[] arctans5 = de_emphasis(arctans, 0.67523190665); // fc = 3kHz/48kHz = 0.0625, e^(-2pi*0.0625) log.stop("FIR: "); FileStream fs = new FileStream(wavefilename, FileMode.CreateNew); BinaryWriter bw = new BinaryWriter(fs, Encoding.ASCII); write_wave_header(bw, (uint)arctans5.Length * 2); double maxAmp = 0.0; for (var i = 0; i < arctans5.Length; i++) { double val = Math.Abs(arctans5[i]); if (maxAmp < val) { maxAmp = val; } } for (var i = 0; i < arctans5.Length; i++) { double v = arctans5[i]; int val = (int)((v / maxAmp) * (1 << 15) + (1 << 12)); short vv = (val > 0x7FFF) ? (short)0x7FFF : (val < -0x8000) ? (short)-0x8000 : (short)val; bw.Write(vv); } // MessageBox.Show("maxAmp = " + maxAmp); bw.Close(); fs.Close(); }
private void button_fm_after_demod_Click(object sender, EventArgs e) { string msg = ""; OpenFileDialog dlg = new OpenFileDialog(); if (DialogResult.OK == dlg.ShowDialog()) { TimeStampLog log = new TimeStampLog(); log.start(); Int32[] dat; read_atan_data_file(dlg.FileName, out dat); log.stop("Read File: "); fm_demodulate3(dat, dlg.FileName + ".wav", log); string[] buf = log.getLog(); for (var i = 0; i < buf.Length; i++) { msg += buf[i] + "\n"; } MessageBox.Show(msg); } }
private void button_fm_Click(object sender, EventArgs e) { string msg = ""; double fm_tune_freq = Convert.ToDouble(textBox_fm_freq.Text) * 1.0e+6; OpenFileDialog dlg = new OpenFileDialog(); if (DialogResult.OK == dlg.ShowDialog()) { TimeStampLog log = new TimeStampLog(); log.start(); Int16[] dat = read_data_file(dlg.FileName); log.stop("Read File: "); fm_demodulate(fm_tune_freq, dat, dlg.FileName + ".wav", log); string[] buf = log.getLog(); for (var i = 0; i < buf.Length; i++) { msg += buf[i] + "\n"; } MessageBox.Show(msg); } }