{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tuner Upper Problem Demo\n",
    "On the amateur radio HF bands, operators need to tune their high power amplifiers that use vacuum tubes.  The final impedance matching network needs to be retuned everytime the frequency of operation is changed by more than about 100 KHz.  When an operator tunes his amplifier, the signal sounds like a sinewave at a frequency determined by the transmitter being tuned.  Normally operators listen to make sure nobody is using the frequency before tuning up, but the way the ionesphere works, you often cannot hear an operator between 100 and maybe 500 miles away, because his signals bounce over you.  This causes a rather frequent problem.  You will be listening to a friend, and all of a subben a sinewave is drowning him out.  \n",
    "\n",
    "This demo shows how an adaptive LMS filter can be used to solve the problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ALSA lib pcm_dmix.c:1108:(snd_pcm_dmix_open) unable to open slave\n",
      "ALSA lib pcm.c:2564:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear\n",
      "ALSA lib pcm.c:2564:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe\n",
      "ALSA lib pcm.c:2564:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side\n",
      "ALSA lib pcm_route.c:869:(find_matching_chmap) Found no matching channel map\n",
      "Cannot connect to server socket err = No such file or directory\n",
      "Cannot connect to server request channel\n",
      "jack server is not running or cannot be started\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "Cannot connect to server socket err = No such file or directory\n",
      "Cannot connect to server request channel\n",
      "jack server is not running or cannot be started\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port\n",
      "ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port\n",
      "ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card\n",
      "ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card\n",
      "ALSA lib pcm_dmix.c:1108:(snd_pcm_dmix_open) unable to open slave\n",
      "Cannot connect to server socket err = No such file or directory\n",
      "Cannot connect to server request channel\n",
      "jack server is not running or cannot be started\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n",
      "ans = 0\n",
      "ans = 0\n"
     ]
    }
   ],
   "source": [
    "% Demonstration of LMS algorithm for noise cancellation.  Tuner upper problem.\n",
    "% Rich Kozick, Spring 1997\n",
    "% Rob Frohne's  modifications for Macintosh 2000\n",
    "% and Linux 2006 or so.\n",
    "\n",
    "pkg load signal\n",
    "clear all\n",
    "\n",
    "mu = 0.1;\n",
    "\n",
    "Fs=8000; % 8 Khz sampling for Linux.\n",
    "T0 = 2;  % 2 seconds\n",
    "\n",
    "system(\"espeak 'Speak the signal.'\");\n",
    "st = record(T0,Fs);\n",
    "%st=audioread('Hello.wav');\n",
    "st=st(:,1);\n",
    "\n",
    "system(\"espeak 'Here is the signal.'\")\n",
    "soundsc(st);\n",
    "\n",
    "Ls = length(st);\n",
    "T0=length(st)/Fs;\n",
    "%  Make the tuner upper noise or even several at the same time.\n",
    "t=0:1/Fs:T0-1/Fs;\n",
    "n =  5*(sin(2*pi*100*pi*t) + 5*cos(2*pi*600*t) + 4*sin(2*pi*850*t));\n",
    "\n",
    "% Add him or them to the desired signal.\n",
    "x = st' + n;\n",
    "\n",
    "system(\"espeak 'Here is the noisy signal.'\")\n",
    "soundsc(x,Fs);\n",
    "\n",
    "N = 64;         % Length of adaptive filter\n",
    "\n",
    "% LMS algorithm for adaptive noise cancellation\n",
    "\n",
    "h = ones(N,1);\n",
    "\n",
    "for k=N:Ls\n",
    "  xk = x(k:-1:(k-N+1));\n",
    "  y(k) = h'*xk';\n",
    "  e(k) = y(k);\n",
    "  h = h - 2*mu*e(k)*xk'/(xk*xk');\n",
    "end\n",
    "\n",
    "% The signal estimate is in the vector e\n",
    "system(\"espeak 'Here is a scaled version of the tail of the cleaned signal.'\");\n",
    "skip =1000;\n",
    "soundsc(e(skip:length(e)),Fs);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Octave",
   "language": "octave",
   "name": "octave"
  },
  "language_info": {
   "file_extension": ".m",
   "help_links": [
    {
     "text": "GNU Octave",
     "url": "https://www.gnu.org/software/octave/support.html"
    },
    {
     "text": "Octave Kernel",
     "url": "https://github.com/Calysto/octave_kernel"
    },
    {
     "text": "MetaKernel Magics",
     "url": "https://metakernel.readthedocs.io/en/latest/source/README.html"
    }
   ],
   "mimetype": "text/x-octave",
   "name": "octave",
   "version": "4.4.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
