Skip to content

NoiseTinker/NamiLib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NamiLib

A small and simple library for basic signal generation, processing and software defined radio implemented in C.

Written to learn about DSP and SDR.

Features

  • Sine, square, triangle and sawtooth Periodic functions.
  • ADSR and raised-cosine Envelope function.
  • Parameterized Wave from periodic function and envelope.
  • Sampler to take samples from a Wave.
  • PCM Frame to handle the samples.
  • Gain applies gain to a frame.
  • Oscillator producing real or complex (IQ) signal.
  • Fft using Ooura's FFT implementations.
  • FrameWriter to write frames to a file.
  • FrameReader to read frames from a file or socket.
  • FramePlayer to play frames to sound card.
  • Demodulator for SSB/CW and AM.

Backlog

  • Demodulator for FM.
  • Modulator for SSB/CW, AM and FM.
  • AGC automatic gain control.
  • FrameRecorder to record frames from sound card.
  • Stft to create waterfall displays etc.
  • Rectangular, Hamming or Hanning Window.
  • Goertzel algorithm for DTMF detection.
  • Waypoint periodic function.

Dependencies

Depends on portaudio and rtl-sdr.

sudo port install portaudio rtl-sdr

Build

make

Test

make test

Build Example

gcc -I../src/include -lportaudio ../out/libNami.a play_sdr.c -o play_sdr

Building blocks

The library provide a few building blocks.

Wave form synthesis

| Periodic function | ( -1 <= y <= 1, 0 <= x <= 2π )
          |
          \---------------> * <--------- | Envelope |
                            |
                            V
                        | Wave | <-  f, phase, A
                            |
                            V
                       | Sampler | <- sampling frequency, t1, t2 
                            |
                            V
                        | Frame | <- encoding
                            |
                            V
                     | FrameWriter |

Signal processing

| FrameReader |
      |
      V
  | Frame |
      |
      V
     FFT()
      |
      V
ComplexNumber[]     ComplexNumber[]
      |                   |
      \---------*---------/
                |
                V
              IFFT()
                |
                V
            | Frame |

Software Define Radio

| FrameRecorder |
       |
       V
   | Frame |
       |
       V
    | AGC |               | Oscillator |
       |                        |
       \--> | Demodulator | <---/
                   |
                   V
               | Frame | -> | Stft | -> | ComplexFrame |
                   |
                   V
            | FramePlayer |

Streams

| FrameRecorder |              | FrameReader |
        |                            |
        V                            V
    | Frame |                    | Frame |
        |                            |
        \--------------*-------------/
                       |
                      ...
                       |
                       V
        /--------------*-------------\
        |                            |
| FramePlayer |                | FrameWriter |

Examples

Sine wave with raised cosine envelope (clickless Morse dit)

Code

Periodic periodic;
Envelope envelope;
RaisedCosineParameters params;
Wave wave;
Sampler sampler;
Frame frame;
FrameWriter writer;
uint8_t data[FRAME_SIZE] = {0};
double angularFrequency = nami_angular_frequency_from_frequency(700);

params.rise_time = 0.020;
params.fall_time = 0.020;
params.sustain_time = 0.040;

nami_set_function(&periodic, &nami_sine_wave);
nami_set_envelope_function(&envelope, nami_raised_cosine, (void*)&params);
nami_set_periodic(&wave, &periodic, 0.5, 0, angularFrequency);
nami_set_envelope(&wave, &envelope);
nami_init_sampler(&sampler, &wave, 0, 0.080, SAMPLE_RATE);
nami_init_frame(&frame, UINT8, &data, FRAME_SIZE);
nami_open_writer(&writer, "morse_dit.raw");

while (nami_samples_left(&sampler) > 0) {

    nami_fill_frame(&sampler, &frame);
    nami_write_frame(&writer, &frame);
}

nami_close_writer(&writer);

Waveform

Waveform as viewed in Audacity:

MorseDit

Morse Dit (Ogg Vorbis)

PSK31 Zeros

Code

Periodic periodic;
Envelope envelope;
RaisedCosineParameters params;
Wave wave;
Sampler sampler;
Frame frame;
FrameWriter writer;
uint8_t data[FRAME_SIZE] = {0};
double angularFrequency = nami_angular_frequency_from_frequency(700);

params.rise_time = 0.016;
params.fall_time = 0.016;
params.sustain_time = 0;

nami_set_function(&periodic, &nami_sine_wave);
nami_set_envelope_function(&envelope, nami_raised_cosine, (void*)&params);
nami_set_periodic(&wave, &periodic, 0.5, 0, angularFrequency);
nami_set_envelope(&wave, &envelope);
nami_init_sampler(&sampler, &wave, 0, 0.032, SAMPLE_RATE);
nami_init_frame(&frame, UINT8, &data, FRAME_SIZE);
nami_open_writer(&writer, "psk31_zeros.raw");

for (int i = 0; i < 40; i++) {

    while (nami_samples_left(&sampler) > 0) {

        nami_fill_frame(&sampler, &frame);
        nami_write_frame(&writer, &frame);
    }

    wave.phase += M_PI;

    nami_set_current_sample_time(&sampler, 0);
}

nami_close_writer(&writer);

Waveform

Waveform as viewed in Audacity:

Psk31Zeros

PSK31 Zeros (Ogg Vorbis)

Reference

About

A library for basic signal generation, processing and software defined radio.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages