{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "import cmsisdsp as dsp\n",
    "import numpy as np\n",
    "from numpy import pi as PI\n",
    "from pylab import figure, clf, plot, xlabel, ylabel, xlim, ylim, title, grid, axes, show,semilogx, semilogy\n",
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def chirp(fmin,fmax,dur,t):\n",
    "    c=(fmax-fmin)/dur\n",
    "    return(np.sin(2.0*PI*(c/2*t*t+ fmin * t)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "sampling_frequency = 8000 \n",
    "duration = 4096/sampling_frequency # seconds\n",
    "time = np.arange(0,duration,1.0 / sampling_frequency)\n",
    "fmin=10\n",
    "fmax=500\n",
    "\n",
    "c=(fmax-fmin)/duration\n",
    "signal=chirp(fmin,fmax,duration,time)\n",
    "nb=len(signal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1b3c4c7d0f0>]"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 38772 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(signal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Some useful functions to convert between f32 and q31 format.\n",
    "def q31sat(x):\n",
    "     if x > 0x7FFFFFFF:\n",
    "          return(np.int32(0x7FFFFFFF))\n",
    "     elif x < -0x80000000:\n",
    "          return(np.int32(0x80000000))\n",
    "     else:\n",
    "          return(np.int32(x))\n",
    "\n",
    "q31satV=np.vectorize(q31sat)\n",
    "\n",
    "def toQ31(x):\n",
    "     return(q31satV(np.round(x * (1<<31))))\n",
    "\n",
    "def Q31toF32(x):\n",
    "     return(1.0*x / 2**31)\n",
    "    \n",
    "# The return of a RFFT is complex. But cmsidsp is returning a flattened buffer with\n",
    "# twice the size. This function is doing the convertion to complex numbers.\n",
    "def asComplex(ar):\n",
    "    return(ar[0::2] + 1j * ar[1::2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize the RFFT Q31\n",
    "rfftq31=dsp.arm_rfft_instance_q31()\n",
    "status=dsp.arm_rfft_init_q31(rfftq31,nb,0,1)\n",
    "# Convert the input signal to Q31\n",
    "signalRQ31=toQ31(signal)\n",
    "# Compute the RFFT\n",
    "result = dsp.arm_rfft_q31(rfftq31,signalRQ31)\n",
    "# Convert the output spectrum to complex float and apply a scaling\n",
    "result=asComplex(Q31toF32(result)*(1 << 12))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14908 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "mag=10.0 * np.log(np.abs(result))\n",
    "plot(mag)\n",
    "title(\"RFFT Q31\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
