Skip to content

Commit

Permalink
Merge branch 'nextRelease'
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankReiser committed Nov 27, 2023
2 parents 3c28fc0 + 0db4691 commit 79fbcc3
Show file tree
Hide file tree
Showing 14 changed files with 3,092 additions and 88 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)

project(
ReiserRT_ChirpingPhasor
VERSION 1.1.5
VERSION 2.0.1
DESCRIPTION "ReiserRT Complex Chirping Phasor Tone Generator" )

# Set up compiler requirements
Expand Down
59 changes: 45 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Frank Reiser's C++11 implementation of a fast and accurate, "chirping" sin/cos waveform pair (I/Q) generator.
This library component is dependent on the ReiserRT_FlyingPhasor shared object library.
This component has been tested to be interface-able with C++20 compiles.
Note that the compiled library code is built using the c++11 standard.

## Overview

Expand All @@ -29,30 +27,62 @@ domain range limits since it does not track, or care about, "cycles". Angular ve
Acceleration may be halted or otherwise modified via the `modifyAccel` operation.

## Details
A little more needs to be said regarding the "loving care" mentioned above.
A little more should be said regarding the "loving care" mentioned above.
This tone generator is taking advantage of Euler's mathematics of the unit circle. When you multiply two phasors,
you multiply the magnitudes and add the angles. When applied to unit vectors (magnitudes of one),
the resultant magnitude stays one, you simply add the angles. Our state data unit vectors are in rectangular form,
we simply preform a complex multiply in rectangular form, the resultant magnitude of which may drift away from one.
Because of this, a re-normalization cycle must be preformed on some periodic basis and this adds to the cost.
This tone generator performs this re-normalization every other sample. This was chosen for two reasons.
One, it puts any resultant spur at the Nyquist (edge of bandwidth). Two, because at every other sample,
the re-normalization required is minimal, keeping its noise contribution minimum.
Additionally, with such small errors, a simple and inexpensive linear approximation is all that is required to maintain
stability. Accuracy is such that it is "almost" immeasurably worse. You be the judge.
1) It puts any resultant re-normalization spur at the Nyquist rate (edge of bandwidth).
2) Re-normalizing at every other sample, keeps its noise contribution minimal.
Additionally, with such small errors at every other cycle,
a simple and inexpensive linear approximation is all that is required to maintain stability.

Regarding the "state data", this tone generator was designed to generate a single chirp per instance.
An instance is constructed with an initial acceleration, omega zero and a phase angle (phi).
When an initial number of samples are requested from an instance, they are delivered
from the starting phase angle at an accelerating radians per sample, rate. Subsequent sample requests,
are delivered in phase (continuous) with the previous samples delivered. An instance
may be "reset" however, to produce a different chirp. Resetting re-initializes all "state data"
as if the object were just constructed. The amount of state data maintained is fairly small.

# Example Data Characteristics
Here, we present some example data created with the 'streamChirpingPhasor' utility program included
with the project. We generated 1024 samples with an acceleration of pi/16384 radians per sample squared,
with an omega zero of of zero and a starting phase of zero.
This data is plotted below:

Figure 1 - Example Flying Phasor Sample Series Data

![Figure 1](graphics/figure1.svg)

From the figure, we can see a linearly increasing frequency. The data is complex in nature. If you only
need the imaginary value, that can be extracted. The real value is calculated simultaneously for free
and may be useful for compensating for, or for creating doppler shifts with complex signal data.

# Interface Compatibility
This component has been tested to be interface-able with C++20 compiles. Note that the compiled library code
is built using the c++11 standard. API/ABI stability will be maintained between minor versions of this project.

# Dependencies
This component is dependent upon ReiserRT_FlyingPhasor, version 3.0 in order to configure and build.

# Thread Safety
This tone generator is NOT "thread safe". There are no concurrent access mechanisms in place and there is no good reason
for addressing this. To the contrary, state left by one thread would make no sense to another,
never mind the concurrency issues. Have threads use their own unique instances.
This tone generator is not "thread safe". There are no concurrent access mechanisms
in place and there is no good reason for addressing this. To the contrary,
state left by one thread would make little sense to another, never mind the concurrency issues.
Have threads use their own unique instances.

# Acknowledgements
As with ReiserRT_FlyingPhasor, this algorithm was derived from something I saw on StackExchange. It however was
a non-chirping variety. This chirping variety is a compounding of that algorithm to achieve a dynamic rate.
It is essentially a FlyingPhasorToneGenerator within a FlyingPhasorToneGenerator.
a non-chirping variety. This chirping variety is a compounding of that algorithm to achieve a dynamic rate
as opposed to a fixed one. It is essentially a FlyingPhasorToneGenerator within a FlyingPhasorToneGenerator.

## Building and Installation
Roughly as follows:
This project requires cmake version 3.15 or higher. The procedure for configuring and building is
roughly as follows:

1) Obtain a copy of the project
2) Create a build folder within the project root folder.
3) Switch directory to the build folder and run the following
Expand All @@ -70,4 +100,5 @@ Roughly as follows:
```
sudo cmake --install .
```

Please see the "tests" and "sundry" folders for examples on how to use the ChirpingPhasor in
your own projects.
32 changes: 32 additions & 0 deletions graphics/PlotNotes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# I wrote this, so I can remember how I accomplished the graphics in the README
# in case I ever need to redo them. The project needs to be built and ideally installed
# beforehand.

################### FIGURE 1 #######################
# To Generate the "Figure 1 - Example Chirping Phasor Sample Series Data" graphic contained in the README file,
# I used the below command off in some directory outside the source tree:
streamChirpingPhasor --includeX --streamFormat=b32 --chunkSize=1024 > chirpingPhasorB32.in

# The output binary file contains three binary columns (sampleNum, real, imaginary) for 1024 samples.
# The data is in 32 bit precision and by default has a acceleration of pi/16384 rads/sample^2,
# an omegaZero of zero and a phase of zero. Note that 32 bit precision is more than adequate for a plot.

# In the same directory where the file 'chirpingPhasorB32.in' sits, enter gnuplot.
# You will need gnuplot to be installed obviously to do this.
gnuplot

set term svg size 520, 360 font "Helvetica,12" background rgb "grey90"
set output 'figure1.svg'
set xrange [0:1023]
set yrange [-1.5:1.5]
set xtics 128
set ytics 0.5
set grid xtics
set grid ytics
set xlabel "Sample Number (n)"
set ylabel "Amplitude"
set title "ChirpingPhasor accel=pi/16384, omega0=0.0, phi=0.0"
set title "ChirpingPhasor accel=pi/16384 rads/sample^2, omega0=0.0, phi=0.0"

# This is one long line, not two lines. Output goes directly to the file 'figure1.svg'.
plot 'chirpingPhasorB32.in' binary format="%uint%float%float" using 1:3 with lines title "imag(n)", 'chirpingPhasorB32.in' binary format="%uint%float%float" using 1:2 with dots title "real(n)"
Loading

0 comments on commit 79fbcc3

Please sign in to comment.