• Stars
    star
    311
  • Rank 134,521 (Top 3 %)
  • Language
    C#
  • License
    MIT License
  • Created over 5 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

.NET library for creating spectrograms (visual representations of frequency spectrum over time)

Spectrogram

CI Nuget

Spectrogram is a .NET library for creating spectrograms from pre-recorded signals or live audio from the sound card. Spectrogram uses FFT algorithms and window functions provided by the FftSharp project, and it targets .NET Standard so it can be used in .NET Framework and .NET Core projects.

"I'm sorry Dave... I'm afraid I can't do that"

Quickstart

  • This code generates the spectrogram above.

  • Source code for the WAV reading method is at the bottom of this page.

(double[] audio, int sampleRate) = ReadMono("hal.wav");
var sg = new SpectrogramGenerator(sampleRate, fftSize: 4096, stepSize: 500, maxFreq: 3000);
sg.Add(audio);
sg.SaveImage("hal.png");

Windows Forms

If you're using Spectrogram in a graphical application you may find it helpful to retrieve the output as a Bitmap which can be displayed on a Picturebox:

pictureBox1.Image = sg.GetBitmap();

I find it helpful to put the Picturebox inside a Panel with auto-scroll enabled, so large spectrograms which are bigger than the size of the window can be interactively displayed.

Real-Time Spectrogram

An example program is included in this repository which demonstrates how to use NAudio to get samples from the sound card and display them as a spectrogram. Spectrogram was designed to be able to display spectrograms with live or growing data, so this is exceptionally easy to implement.

To do this, keep your Spectrogram at the class level:

SpectrogramGenerator sg;

public Form1()
{
    InitializeComponent();
    sg = new SpectrogramGenerator(sampleRate, fftSize: 4096, stepSize: 500, maxFreq: 3000);
}

Whenever an audio buffer gets filled, add the data to your Spectrogram:

private void GotNewBuffer(double[] audio)
{
    sg.Add(audio);
}

Then set up a timer to trigger rendering:

private void timer1_Tick(object sender, EventArgs e){
    Bitmap bmp = sg.GetBitmap(intensity: .4);
    pictureBox1.Image?.Dispose();
    pictureBox1.Image = bmp;
}

Review the source code of the demo application for additional details and considerations. You'll found I abstracted the audio interfacing code into its own class, isolating it from the GUI code.

Song-to-Spectrogram

This example demonstrates how to convert a MP3 file to a spectrogram image. A sample MP3 audio file in the data folder contains the audio track from Ken Barker's excellent piano performance of George Frideric Handel's Suite No. 5 in E major for harpsichord (The Harmonious Blacksmith). This audio file is included with permission, and the original video can be viewed on YouTube.

(double[] audio, int sampleRate) = ReadMono("song.wav");

int fftSize = 16384;
int targetWidthPx = 3000;
int stepSize = audio.Length / targetWidthPx;

var sg = new SpectrogramGenerator(sampleRate, fftSize, stepSize, maxFreq: 2200);
sg.Add(audio);
sg.SaveImage("song.png", intensity: 5, dB: true);

Notice the optional conversion to Decibels while saving the image.

If you listen to the audio track while closely inspecting the spectrogram you can identify individual piano notes and chords, and may be surprised by the interesting patterns that emerge around trills and glissandos.

Spectrogram Information

The Spectrogram's ToString() method displays detailed information about the spectrogram:

Console.WriteLine(sg);
Spectrogram (2993, 817)
  Vertical (817 px): 0 - 2,199 Hz, FFT size: 16,384 samples, 2.69 Hz/px
  Horizontal (2993 px): 2.96 min, window: 0.37 sec, step: 0.06 sec, overlap: 84%

Colormaps

These examples demonstrate the identical spectrogram analyzed with a variety of different colormaps. Spectrogram colormaps can be changed by calling the SetColormap() method:

(double[] audio, int sampleRate) = ReadMono("hal.wav");
var sg = new SpectrogramGenerator(sampleRate, fftSize: 8192, stepSize: 200, maxFreq: 3000);
sg.Add(audio);
sg.SetColormap(Colormap.Jet);
sg.SaveImage($"jet.png");
Viridis Greens Blues Grayscale GrayscaleR

Mel Spectrogram

Analytical spectrograms aimed at achieving maximum frequency resolution are presented using linear scaling, where every row of pixels is evenly spaced in the frequency domain. However, biological sensory systems tend to be logarithmic, and the human ear can differentiate frequency shifts better at lower frequencies than at higher ones.

To visualize frequency in a way that mimics human perception we create a spectrogram that represents lower frequencies using a large portion of the image, and condense higher frequency ranges into smaller rows of pixels toward the top of the image. The Mel Scale is commonly used to represent power spectral density this way, and the resulting Mel Spectrogram has greatly reduced vertical resolution but is a better representation of human frequency perception.

Cropped Linear Scale (0-3kHz) Mel Scale (0-22 kHz)

Amplitude perception in humans, like frequency perception, is logarithmic. Therefore, Mel spectrograms typically display log-transformed spectral power and are presented using Decibel units.

(double[] audio, int sampleRate) = ReadMono("hal.wav");
var sg = new SpectrogramGenerator(sampleRate, fftSize: 4096, stepSize: 500, maxFreq: 3000);
sg.Add(audio);

// Create a traditional (linear) Spectrogram
sg.SaveImage("hal.png");

// Create a Mel Spectrogram
Bitmap bmp = sg.GetBitmapMel(melSizePoints: 250);
bmp.Save("halMel.png", ImageFormat.Png);

Read Data from an Audio File

You should customize your file-reading method to suit your specific application. I frequently use the NAudio package to read data from WAV and MP3 files. This function reads audio data from a mono WAV file and will be used for the examples on this page.

(double[] audio, int sampleRate) ReadMono(string filePath, double multiplier = 16_000)
{
    using var afr = new NAudio.Wave.AudioFileReader(filePath);
    int sampleRate = afr.WaveFormat.SampleRate;
    int bytesPerSample = afr.WaveFormat.BitsPerSample / 8;
    int sampleCount = (int)(afr.Length / bytesPerSample);
    int channelCount = afr.WaveFormat.Channels;
    var audio = new List<double>(sampleCount);
    var buffer = new float[sampleRate * channelCount];
    int samplesRead = 0;
    while ((samplesRead = afr.Read(buffer, 0, buffer.Length)) > 0)
        audio.AddRange(buffer.Take(samplesRead).Select(x => x * multiplier));
    return (audio.ToArray(), sampleRate);
}

More Repositories

1

Csharp-Data-Visualization

Resources for visualizing data using C# and the .NET platform
C#
1,009
star
2

FftSharp

A .NET Standard library for computing the Fast Fourier Transform (FFT) of real or complex data
C
313
star
3

Python-GUI-examples

A growing collection of bare-bones GUI examples for python (PyQt4, Python 3)
Python
238
star
4

AVR-projects

A collection of standalone AVR projects written in C
C
161
star
5

pyABF

pyABF is a Python package for reading electrophysiology data from Axon Binary Format (ABF) files
Jupyter Notebook
101
star
6

diyECG-1opAmp

A surprisingly good ECG circuit using a single op-amp and some Python software
Python
98
star
7

SoundCardECG

Display ECG signals in real time using a sound card interface and an AD8232
C#
85
star
8

pyHH

A simple Python implementation of the Hodgkin-Huxley spiking neuron model
Python
36
star
9

code-notes

notes and reusable code for various programming languages
C++
34
star
10

QuickPlot

Experimental Plotting Library for .NET
C#
31
star
11

FtdiSharp

A .NET library for interfacing FTDI USB controller ICs
C#
25
star
12

SWHLab

Python tools for analysis of whole-cell patch-clamp electrophysiological data
Python
20
star
13

SeriPlot

Realtime Serial Data Plotter
C#
20
star
14

Local-LLM-csharp

Run a LLM locally to answer questions about documents using C#
HTML
19
star
15

USB-Counter

Open-source USB frequency counter
C
18
star
16

BasicTimer

A basic timer app for Windows
C#
17
star
17

pyScreenCapture

Screen capture video (with cursor) using Python
Python
17
star
18

md2html-php

A flat-file dynamic markdown-to-HTML site generator using PHP
PHP
15
star
19

pyABFauto

Automatic analysis (and graphing) of ABF files
Python
14
star
20

RasPi-Frequency-Counter

Raspberry PI RF Frequency Counter with Python Interface
Python
14
star
21

HHSharp

Interactive Hodgkin-Huxley neuron simulator
C#
13
star
22

FSKview

A high resolution spectrogram for viewing FSK signals in real time
C#
13
star
23

pyTENMA

Python interface to TENMA multimeter serial data
Python
12
star
24

QRSS-VD

QRSS Viewer for Python 2
Python
12
star
25

Mystify

A modern implementation of a classic screensaver
C#
12
star
26

SwarmFit

A .NET package for fitting curves to data using particle swarm optimization
C#
11
star
27

FTFlash

A tool for reading and writing data in SPI flash memory chips using a FT232H
C#
9
star
28

QRSSplus

QRSS Plus: live QRSS grabbers from around the world
C#
9
star
29

ADC-10-F103C

Software and Notes for 10-Channel ADC Board
C#
9
star
30

WsprSharp

.NET Standard library for encoding/decoding messages using the WSPR protocol
HTML
8
star
31

QRSS-hardware

A collection of resources related to QRSS hardware (TX and RX)
C
8
star
32

LJPcalc

Liquid Junction Potential Calculator
C#
8
star
33

ABFview

Electrophysiology data viewer for Axon Binary Format (ABF) files
C#
7
star
34

SciTIF

A .NET library for working with scientific image data in TIFF files
C#
7
star
35

CsvPlot

Interactively display data from CSV files
C#
7
star
36

NumberSpeaker

Arduino library for reading numbers using a speaker
C
5
star
37

AbfSharp

A .NET interface for Axon Binary Format (ABF) files
HTML
5
star
38

pyHamLog

ham radio logging software with a web interface (designed for school club roundup)
Python
5
star
39

repo-badge

Display GitHub repository statistics using Vanilla JS
5
star
40

swharden

Scott W Harden on GitHub
4
star
41

ScanAGator

A tool for calculating calcium levels (ΔF/F) from two-photon line scans
C#
4
star
42

ABF-Tag-Editor

A standalone application to modify comment tags in ABF files
C#
4
star
43

QRSS-Uploader

Uploads QRSS images to a FTP server every 10 minutes
C#
4
star
44

vsABF

A modern .NET interface to files in the Axon Binary Format (ABF)
C#
4
star
45

ImageJ-Python-plugin

boilerplate python plugin for ImageJ / FIJI
Python
4
star
46

Washcloth

A .NET Standard library for reading XML documentation using reflection
C#
4
star
47

Lopora

QRSS Beacon Reception Program
Python
4
star
48

FlaskABF

Python-based web application to browse and analyze electrophysiology data
HTML
4
star
49

LivePictureViewer

A picture viewer that rapidly updates when the image file on disk changes
C#
4
star
50

webinspect

Python module to allow users to inspect python objects in a web browser
Python
4
star
51

SWHarden.com

The personal website of Scott W Harden
HTML
4
star
52

ROI-Analysis-Pipeline

Tools for automated analysis of fluorescent microscopy data
Shell
3
star
53

ABF-SDK

Resources for working with Axon Binary Format (ABF) Files
C++
3
star
54

QRSSplus-Downloader

A Windows application to automatically download QRSS grabber images
C#
3
star
55

Tmoji

A taskbar app to quickly copy emoji and special symbols
C#
3
star
56

WpfPingMonitor

Windows application to display ping latency
C#
3
star
57

RasterSharp

A .NET library for working with images in memory
C#
3
star
58

ephys-projects

personal projects related to electrophysiology data analysis and visualization
C#
2
star
59

NDepend-Badges

C#
2
star
60

Statix

C# Static Site Generator
C#
2
star
61

SWHarden-User-Controls

A collection of custom user controls for .NET
C#
2
star
62

psk-experiments

Phase-shift keying (PSK) notes and resources
C#
2
star
63

Csharp-Image-Analysis

Code examples and notes for analyzing image data using C#
C#
2
star
64

StarGraph

A cloud application for generating historical graphs of GitHub stars
C#
2
star
65

Palila

Minimal, hackable, dependency-free Python static site generator
HTML
2
star
66

ABF-Scale-Fixer

An application to modify header values of ABF2 files
C#
2
star
67

iot-weather-station

Wi-Fi weather station using NodeMCU and ESP8266
HTML
2
star
68

ScottPlotStats

Azure Functions for logging and plotting ScottPlot NuGet package downloads
C#
2
star
69

memtest

Notes and code for calculating cell membrane parameters from electrophysiological recordings
Jupyter Notebook
2
star
70

JLJP

Java application for calculating liquid junction potential (LJP)
Java
2
star
71

Java-Boilerplate

Example Java desktop app with tests and CI using GitHub Actions
Java
1
star
72

swharden.com-2021

code and resources related to my personal website
PHP
1
star
73

Bootstrapped-KS2

Tools for bootstrapping the Kolmogorov-Smirnov statistic on 2 samples
C#
1
star
74

duplicate-code-finder

A simple Python script to identify duplicate lines in the code base of any programming language
Python
1
star
75

AliCalc

Aliquot Calculator for Electrophysiology
HTML
1
star
76

patch

A Student's Guide to Patch-Clamp Electrophysiology
HTML
1
star
77

QRSS-Viewer

An open source QRSS spectrograph for Windows
C#
1
star
78

Microscopy

miscellaneous notes and tools to aid the scientific microscopist
Python
1
star
79

ColorblindEnhancer

A Windows tool that enhances color perception for people with color vision deficiencies
C#
1
star
80

originpro

Source code for the originpro Python package
Python
1
star
81

Maui.Graphics

Source for https://maui.graphics
HTML
1
star
82

SWHLabPHP

Dynamically generated web platform to browse electrophysiology data
PHP
1
star
83

govee-plot

Tools for interactively plotting Govee temperature and humidity data
Jupyter Notebook
1
star
84

double-pendulum-dotnet

C# implementation of the double pendulum problem
C#
1
star
85

AbfAuto

automated analysis of electrophysiology data in ABF files
C#
1
star
86

AbfConvert

Tools for automated conversion of ABF files to ATF, CSV, and other useful formats
C#
1
star
87

MatrixWall

Falling green Unicode characters on a dark background implemented using Vanilla JavaScript
JavaScript
1
star
88

PrairieView-Quick-Loader

ImageJ plugin to quickly load multiphoton imaging data from PrairieView folders
Java
1
star
89

Exponential-Fit-CSharp

Exponential fit code examples using C#
C#
1
star
90

AbfVideo

Generate real-time video files from electrophysiology data
C#
1
star
91

qrss.org

A collection of resources for ultra-narrowband amateur radio experimentation
HTML
1
star
92

swharden.RoiSelect

A .NET Package that facilitates working with regions of interest (ROIs) for imaging data in GUI applications
C#
1
star
93

ABF-Spectrogram

Tools for generating FFTs and Spectrograms from ABF files
C#
1
star
94

GitHub-License-Checker

A web app for identifying GitHub repositories lacking license or other important files
HTML
1
star