Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages

VrSigSource.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- */
00002 /*
00003  * Copyright 2001,2003 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 /*
00023  *  Copyright 1997 Massachusetts Institute of Technology
00024  * 
00025  *  Permission to use, copy, modify, distribute, and sell this software and its
00026  *  documentation for any purpose is hereby granted without fee, provided that
00027  *  the above copyright notice appear in all copies and that both that
00028  *  copyright notice and this permission notice appear in supporting
00029  *  documentation, and that the name of M.I.T. not be used in advertising or
00030  *  publicity pertaining to distribution of the software without specific,
00031  *  written prior permission.  M.I.T. makes no representations about the
00032  *  suitability of this software for any purpose.  It is provided "as is"
00033  *  without express or implied warranty.
00034  * 
00035  */
00036 
00037 
00038 #ifndef _VRSIGSOURCE_H_
00039 #define _VRSIGSOURCE_H_
00040 
00041 extern "C" {
00042 #include <math.h>
00043 #include <sys/time.h>
00044 #include <unistd.h>
00045 }
00046 
00047 #include <VrSource.h>
00048 #include <stdlib.h>
00049 
00050 enum {VR_SQUARE_WAVE, VR_TRIANGLE_WAVE, VR_SIN_WAVE, VR_DC_WAVE, VR_COS_WAVE};
00051 
00052 template<class oType> 
00053 class VrSigSource : public VrSource<oType> {
00054 protected:
00055   int wform;
00056   double freq;
00057   double amp;
00058   double time;
00059   oType* buffer;
00060   void incTime() {time = time + 1/(double)getSamplingFrequency();}
00061   double slope() {return 4 * amp * getSamplingFrequency() / freq;}
00062   void createBuffers();
00063 public:
00064   virtual int work2(VrSampleRange output, void *o[]);
00065 
00066   virtual void initialize();
00067 
00068   int getWaveform() {return wform;}
00069   double getAmplitude() {return amp;}
00070   double getFrequency() {return freq;}
00071 
00072   void setWaveform(int w) {wform = w; initialize ();}
00073 
00074   void setAmplitude(double a) {amp = a; initialize ();}
00075 
00076   void setFrequency(double f) {
00077     if (2*f > getSamplingFrequency()) 
00078       freq = getSamplingFrequency()/2; 
00079     else
00080       freq = f;
00081     initialize();
00082   }
00083 
00084 
00085   VrSigSource(double sampling_freq, int wf, double f, double a)  
00086     :wform(wf),freq(f),time(0),buffer(0)
00087   {
00088     setSamplingFrequency (sampling_freq);
00089     amp = a;
00090   }
00091     
00092   VrSigSource(double sampling_freq)
00093     :wform(VR_SIN_WAVE),freq(1000),time(0),buffer(0)
00094   { 
00095     setSamplingFrequency (sampling_freq);
00096     amp = (1 << 8*sizeof(oType) - 1);
00097   }
00098 };
00099 
00100 template<class oType> void
00101 VrSigSource<oType>::createBuffers()
00102 {
00103   unsigned int  i;
00104   
00105   switch (wform) {
00106   case VR_TRIANGLE_WAVE:
00107     for (i = 0;i < getOutputSize(); i++) {
00108       if ((i % (int)(getSamplingFrequency() / freq)) < 
00109           getSamplingFrequency() / 2*freq)
00110         buffer[i] = (oType)(slope() * i - amp);
00111       else
00112         buffer[i] = (oType)(amp - slope() * 
00113                             (i - getSamplingFrequency() / 2*freq));
00114     }
00115     break;
00116 
00117   case VR_SIN_WAVE:
00118     for (i = 0; i < getOutputSize(); i++) {
00119       buffer[i] = (oType)(amp * sin(2*M_PI*freq*time));
00120       incTime();
00121     }
00122     
00123     // average last point to minimize discontinuity on wrap around
00124     i--;        // last point
00125     buffer[i] = (buffer[i-1] + buffer[0]) / 2;
00126     break;
00127 
00128   case VR_COS_WAVE:
00129     for (i = 0; i < getOutputSize(); i++) {
00130       buffer[i] = (oType)(amp * cos(2*M_PI*freq*time));
00131       incTime();
00132     }
00133     
00134     // average last point to minimize discontinuity on wrap around
00135     i--;        // last point
00136     buffer[i] = (buffer[i-1] + buffer[0]) / 2;
00137     break;
00138 
00139   case VR_SQUARE_WAVE:
00140     fprintf (stderr, "VrSigSource: VR_SQUARE_WAVE is broken\a\n");      // FIXME
00141 
00142     for (i = 0; i < getOutputSize();i++) {
00143       if (((int)time % (int)(getSamplingFrequency() / freq)) <  
00144           getSamplingFrequency() / 2*freq)
00145         buffer[i] = (oType)amp;
00146       else
00147         buffer[i] = (oType)amp;
00148     }
00149     break;
00150 
00151   case VR_DC_WAVE:
00152     for (i = 0; i < getOutputSize(); i++) {
00153       buffer[i] = (oType)amp;
00154     }
00155     break;
00156 
00157   default:
00158     abort ();
00159   }
00160 }
00161 
00162 template<class oType> void
00163 VrSigSource<oType>::initialize()
00164 {
00165 #if 1
00166   // pick a burst length that is the maximum of 50 ms or 2048 samples.
00167   double burst_length = 4096.0 / getSamplingFrequency ();
00168   if (0.050 > burst_length)
00169     burst_length = 0.050;
00170 #else
00171   double burst_length = 0.050;
00172 #endif
00173 
00174   // Output is in bursts, rounded to a full period.
00175   // outputSize changes when frequency is changed.
00176 
00177   if (freq == 0.0)      // DC wave generation
00178     setOutputSize ((int) (burst_length * getSamplingFrequency ()));
00179 
00180   else {
00181     double samples_per_cycle = getSamplingFrequency() / freq;
00182     int  cycles_in_burst = (int) ((getSamplingFrequency() * burst_length) / samples_per_cycle);
00183 
00184     setOutputSize ((int) (cycles_in_burst * samples_per_cycle + 0.5));
00185   }
00186   
00187   if (buffer != 0)
00188     delete[] buffer; 
00189   buffer = new oType[getOutputSize()];
00190   createBuffers();
00191 }
00192 
00193 template<class oType> int
00194 VrSigSource<oType>::work2(VrSampleRange output, void *ao[])
00195 { 
00196  oType **o = (oType **)ao;
00197   unsigned int size = output.size;
00198   while (size > 0) {
00199     memcpy((char *)(o[0]),(char *)buffer,getOutputSize()*sizeof(oType));
00200     size -= getOutputSize();
00201     o[0]+=getOutputSize();
00202   }
00203   return output.size;
00204 }
00205 
00206 #endif 

Generated on Tue Mar 30 21:31:53 2004 for GNU Radio by doxygen 1.3.2