Tuesday 2 October 2018

Controlling Tuya (Smart Life) Devices from IFTTT


I have a number of Tuya (Smart Life) lightbulbs and while these are integrated seamlessly with Amazon Voice Services and Google Home, I would also like to be able to control remotely, via Python and also directly by voice from my XMOS VocalFusion™ Stereo Dev Kit (https://www.xmos.com/support/boards?product=37033).
I looked into the Tuya API (https://iot.tuya.com) and decided that it would be much easier to control the lights via IFTTT.

Here is a step-by-step guide.

First we need to enable Webhooks, to allow us to trigger the event via a URL. To do so, search for “Webhook” here : https://ifttt.com/search

Click on "Webhooks" and activate it.


This will give you a URL that looks like : https://maker.ifttt.com/use/xxxxxxxxxxxxxxxxxx
Where xxxxxxxxxxxxxxxxxx is your key, which we will use later.

To create a private Applets go to : https://platform.ifttt.com/p/username/applets/private - note the username is your IFTTT username.



Click New Applet and fill out the fields :




Note for triggering events using URLs I find it easier to ensure there are no spaces in the trigger name e.g. “Turn_On_Light”.
Scroll Down to Action and enter the details :




Enter a Title and Description. I just used “Turn On Light”

Click Save.
Click “Enable On IFTTT”
Turn The Applet On.


You can also create an Applet to turn off the Light. Or to make it easy, just go to the Applet Preview Page and hit “Copy” for the above Applet.
Modify the details of the new Applet and click Save.

You can view your private Applets here : https://platform.ifttt.com/p/username/applets/private

To test your Applet go to here : https://maker.ifttt.com/use/xxxxxxxxxxxxxxxxxx

Enter then name of your Applet “Turn_On_Light” in {event} and click “Test It”.

Now our Applets are setup and tested we only need the URLs for turning on and off the light, these are :

https://maker.ifttt.com/trigger/Turn_On_Light/with/key/xxxxxxxxxxxxxxxxxx

https://maker.ifttt.com/trigger/Turn_Off_Light/with/key/xxxxxxxxxxxxxxxxxx

To trigger the events, just open up the above URLs in a browser and you should be able to remotely control the light.

Alternatively, using Python requests you can do :

import requests
requests.post("https://maker.ifttt.com/trigger/Turn_On_Light/with/key/xxxxxxxxxxxxxxxxxx")

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Thursday 27 September 2018

Calling The SigLib Digital Signal Processing Library From Python

I recently wrote a blog post about

Calling The SigLib Digital Signal Processing Library From Julia

and it made me reflect on my main development environment for prototyping DSP code in Python. I've used SWIG (http://www.swig.org/) as an interface for many years and like its portability but I wondered about how to access a shared library from Python directly so did a bit of investigation and found the ctypes API to be very light weight and very easy to use.

To run SigLib (or any other shared library) from Python is very easy using ctypes.

For SigLib, copy the following code into a file "pythonSigLib.py" :

import ctypes
import numpy as np
import platform as _platform

A = np.array([3.4, 1.8, -2.8, 6.4])
B = np.zeros((A.size), dtype=np.double)

if _platform.system() == "Linux":
   lib = ctypes.cdll.LoadLibrary('./siglib.so')
elif _platform.system() == "Darwin":
   lib = ctypes.cdll.LoadLibrary('./siglib.dylib')
elif _platform.system() == "Windows":
    if _platform.machine().endswith('64'):
        lib = ctypes.cdll.LoadLibrary('.\siglib64.dll')
    else:
        lib = ctypes.cdll.LoadLibrary('.\siglib.dll')

SDA_AbsMax = lib.SDA_AbsMax
SDA_AbsMax.restype = ctypes.c_double
absMax = SDA_AbsMax(ctypes.c_void_p(A.ctypes.data), ctypes.c_int(A.size))

SDA_SortMinToMax = lib.SDA_SortMinToMax
SDA_SortMinToMax(ctypes.c_void_p(A.ctypes.data), ctypes.c_void_p(B.ctypes.data), ctypes.c_int(A.size))

print ('absMax: ', absMax)
print ('B: %s' % B)

Now copy the SigLib shared object (.so, .dll or .dylib) file from /siglib/lib to the current working directory and run :

python pythonSigLib.py

For further information about using SigLib, Python and SWIG, please see this blog post :

How To Access A Windows Library From Python, Using SWIG


To download the evaluation version of the Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/.

Tuesday 25 September 2018

Calling The SigLib Digital Signal Processing Library From Julia

SigLib DSP functions can be called from many languages, such as Python, Java, C#, Perl etc., using the SWIG API.

I've been tracking Julia for a while however V1.0 of Julia was released recently so I thought I would evaluate some of its cool features for DSP prototyping.

Integrating SigLib with Julia was unbelievably easy using the ccall API. If only other languages contained a similarly simple API ;-)

To run SigLib (or any other shared library) from Julia is very easy using ccall.

For SigLib, copy the following code into a file "juliaSigLib.jl" :

A = [3.4, 1.8, -2.8, 6.4]
B = Array{Float64,1}(undef, length(A))

absMax = ccall((:SDA_AbsMax, "siglib"), Float64, (Ptr{Cdouble},Cint), A, length(A))
println("absMax: ", absMax)

ccall((:SDA_SortMinToMax, "siglib"), Cvoid, (Ptr{Cdouble},Ptr{Cdouble},Cint), A, B, length(A))
println("B: ", B)


Now copy the appropriate shared library to the current working directory where you will run juliaSigLib.jl.

OS Source File Destination File
32 Bit Linux siglib/lib/linux/siglib.so.1.0 siglib.so
64 Bit Linux siglib/lib/linux_64/siglib.so.1.0 siglib.so
Raspberry Pi Linux siglib/lib/RaspberryPi/siglib.so.1.0 siglib.so
32 Bit Windows siglib\lib\Microsoft\dynamic_library\Release\siglib.dll siglib.dll
64 Bit Windows siglib\lib\Microsoft\dynamic_library_64\Release\siglib64.dll siglib.dll


To execute the script use :

julia juliaSigLib.jl

Awesome!

Reference : https://docs.julialang.org/en/v0.6.1/manual/calling-c-and-fortran-code/

To download the evaluation version of the Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/.

Saturday 28 July 2018

How To Interpolate The Output Of An FFT To Get Higher Resolution

One common requirement for a frequency analyzer is to maximize the amplitude or frequency estimation estimate for a given sinusoid.

One easy way to do this is to increase the size of the FFT however this comes at the cost of reduced time domain resolution and increased requirement for MIPS and memory.

A low impact solution to increase the resolution of the output is to interpolate the vertex to give a better estimate of the amplitude and frequency of an individual sinusoid.

The overall procedure is shown in the following diagram :

FFT Interpolation Functions

Following the FFT function is a peak detector followed by a peak interpolator.
The interpolation function uses 3 point vertex quadratic interpolation, as shown in the following diagram.

Peak Interpoation

Given that xm is the location of the peak and ym is the magnitude of the peak we can interpolate the peak value efficiently by setting xm-1 == 0, xm == 1, xm+1 == 2, which allows the interpolation to be implemented using the following equations :

a = (ym-1 - ym) * (ym-1 - ym+1)
b = -2 * (ym-1 -ym) + 0.5 * (ym-1 - ym+1)

Interpolated Frequency = -0.5 * b / a
Interpolated Magnitude = ym-1 - 0.25 * b2 / a

To analyze the results, we ran a series of sinusoids through the algorithm and plotted the percentage error. In the following graph we have a normalized sample rate of 1.0 Hz and we are using a 512 point FFT. Plotting the error percentage results between FFT bin 7 (0.013671875 Hz) and FFT bin 9 (0.017578125 Hz).

Interpolation Function Results

We can observe that the maximum gain error percentage = 4.519154% and the maximum frequency error percentage = 0.596755%.

Note, this solution is very accurate when the signal constitutes a single sinusoid or a sinusoid sampled with low noise. However the accuracy will vary with increasing noise an/or adjacent sinusoids - chosing a good windowing function will definitely help with the latter.

Functions to implement the FFT interpoator are included in the SigLib DSP library. To evaluate the Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/.

Friday 22 June 2018

Really Useful Digital Filter Design Spreadsheet

I have uploaded a Really Useful Digital Filter Design Spreadsheet to my Applications Note section : http://www.numerix-dsp.com/appsnotes/ because it no longer appears on the Music-DSP archive, where I originally found it.

It implements the equations from the excellent RBJ Audio-EQ-Cookbook and has some minor fixes.

I have used this spreadsheet for a lot of audio filter design work and also teaching students. I have tried to track down the original author, to give them the credit they deserve. If anyone knows who wrote this spreadsheet then please do ask them to get in touch.

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Monday 19 March 2018

How To Build A Shared Library Under Android Studio And Import Into A Project

I recently wanted to build the SigLib Digital Signal Processing library into an Android library and import into a java application.

My preferred API for cross-language integration is SWIG.

While there are many tutorials available to explain how to create an integrated Android Studio project that includes java and native C++, I struggled to find one that treated the two components separately.

Here is my solution.

Build The Library From The Sources

I used Window 10 as the main development environment and Android Studio for the main application building however I found that it was easier to build the library on the command line under Cygwin.

Install Android Studio from here : https://developer.android.com/studio/install.html

Install NDK, CMake and LLDB from within Android Studio using :
    File | Settings | SDK Tools
    Then tick the boxed and click OK

When you try to build a C program that includes header files such as stdio.h you will receive an error message along the lines of :

  /home/John/Android/Sdk/ndk-bundle/sysroot/usr/include/linux/types.h:21:10: fatal error: 'asm/types.h' file not found
  #include <asm/types.h>
           ^~~~~~~~~~~~~
  1 error generated.

The solution is here : https://github.com/android-ndk/ndk/issues/510
Modify setup-toolchain.mk as follows :

--- a/build/core/setup-toolchain.mk
+++ b/build/core/setup-toolchain.mk
@@ -152 +152 @@
-    -isystem $(SYSROOT_INC)/usr/include/$(header_triple_$(TARGET_ARCH))
+    -isystem $$(call host-path,$(SYSROOT_INC)/usr/include/$(header_triple_$(TARGET_ARCH)))

Open up a Cygwin command prompt and cd to the folder with the library source. Set the path environment variables to the tools :

export PATH=$PATH:/cygdrive/c/Users/John/AppData/Local/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64
export PATH=$PATH:/cygdrive/c/Users/John/AppData/Local/Android/Sdk/ndk-bundle/build

Build an application or library :

ndk-build NDK_PROJECT_PATH=$(pwd) APP_BUILD_SCRIPT=$(pwd)/Android.mk

That should generate the .so and all the necessary .java wrapper files.

Adding The Library To An Android Studio Project

For my project, I started with the simple GraphView (http://www.android-graphview.org/) application : described in this video https://www.youtube.com/watch?v=zbTvJZX0UDk. The source code is available here : https://github.com/mitchtabian/CreateSimpleGraphView. Thanks Mitch for the great tutorial.


Added to app/build.gradle

    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
        jniLibs.srcDir 'siglib_wrap' // Import precompiled libraries in your project.
    }


copy full SWIG installation, from above, to : project/app/src/main/java/com/numerix_dsp/siglib_wrap

copy .so to : project/app/src/main/jniLibs


References

[1] The Main Reference : http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

[2] SWIG Android : http://orx-project.org/wiki/en/tutorials/community/enobayram/swig_android

[3] SWIG Wrapping : https://stackoverflow.com/questions/30110579/how-do-i-wrap-an-existing-c-library-for-use-with-android-studio-with-swig-give

[4] JNI : https://stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio/26693354#26693354

[5] SWIG : http://www.swig.org/Doc3.0/
    http://www.swig.org/Doc3.0/Android.html
    http://www.swig.org/Doc3.0/Java.html

[6] Android Libraries : https://developer.android.com/studio/projects/android-library.html

[7] Android C/C++ : https://developer.android.com/studio/projects/add-native-code.html

[8] Compiling Libraries For Android : https://tariqzubairy.wordpress.com/2012/03/09/arm-binaries-static-library-for-android/

Application Source Code

package com.numerix_dsp.siglib_graph;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

import siglib_wrap.siglib_wrap;
import siglib_wrap.siglib_wrapJNI;
import siglib_wrap.SLSignal_t;
import siglib_wrap.SLSignalFillMode_t;
import siglib_wrap.SWIGTYPE_p_double;

public class SigLib_Graph extends AppCompatActivity {

    private siglib_wrap mSigLib;

    static {
        try {
            System.loadLibrary("siglib_wrap");
        } catch (UnsatisfiedLinkError e) {
            System.err.println("siglib_wrap library failed to load.\n" + e);
            System.exit(1);
        }
    }

    int SAMPLE_LENGTH = 512;

    LineGraphSeries<DataPoint> series;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sig_lib__graph);

        mSigLib = new siglib_wrap();

        SWIGTYPE_p_double SinePhase = mSigLib.new_doubleArray(1);
        mSigLib.doubleArray_setitem(SinePhase, 0, 0.0);

        SWIGTYPE_p_double timeArray = mSigLib.new_doubleArray(SAMPLE_LENGTH);
        SWIGTYPE_p_double nullArray = mSigLib.new_doubleArray(1);

        mSigLib.SDA_SignalGenerate (timeArray,          // Output array pointer
                SLSignal_t.SIGLIB_SINE_WAVE,            // Signal type - Sine wave
                siglib_wrapJNI.SIGLIB_ONE_get(),        // Signal peak level
                SLSignalFillMode_t.SIGLIB_FILL,         // Fill (overwrite) or add to existing array contents
                0.015,                              // Signal frequency
                siglib_wrapJNI.SIGLIB_ZERO_get(),       // D.C. Offset
                siglib_wrapJNI.SIGLIB_ZERO_get(),       // Unused
                siglib_wrapJNI.SIGLIB_ZERO_get(),       // Signal end value - Unused
                SinePhase,                              // Signal phase - maintained across array boundaries
                nullArray,                              // Unused
                SAMPLE_LENGTH);                         // Output dataset length

        GraphView graph = (GraphView) findViewById(R.id.graph1);
        series = new LineGraphSeries<DataPoint>();
        for(int i =0; i<SAMPLE_LENGTH; i++) {
            series.appendData(new DataPoint((double)i, siglib_wrap.doubleArray_getitem(timeArray, i)), true, SAMPLE_LENGTH);
        }
        graph.addSeries(series);
    }
}

The full Android Studio project can be downloaded as part of the SigLib evaluation package, from here : http://www.numerix-dsp.com/eval/

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Sunday 21 January 2018

What's All This FFT Scaling Stuff Anyhow ?

In these earlier blog posts I briefly discussed FFT scaling however in this post I will look into it in more detail.



If I run the following Matlab or Octave code :

x = [0 0.7071 1 0.7071 0 -0.7071 -1 -0.7071];
y = fft(x)
z = ifft(y)

We see that y contains the expected DFT/FFT output (I.E. scaled by N) but z contains the iFFT output scaled to match the original time domain input :

y =
   0.0000 + 0.0000i   0.0000 - 4.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 - 0.0000i   0.0000 + 0.0000i   0.0000 + 4.0000i

z =
   0.00000   0.70710   1.00000   0.70710   0.00000  -0.70710  -1.00000  -0.70710

So Matlab and Octave both include additional operations on the output to multiply the result of the iFFT function by a factor of 1/N so that x == ifft(fft(x)) this makes a lot of sense and is documented in many DSP text books.

If we do the same thing in the SigLib DSP library :

Pseudo code :
    SLData_t x [] = {0., 0.7071, 1.,  0.7071,  0., -0.7071, -1., -0.7071};
    y = SDA_Rfft(x);
    z = SDA_Cifft(y);

We see the following output From SigLib :

y :
[0] =  0.000000 + j 0.000000
[1] =  0.000000 - j 3.999981
[2] =  0.000000 + j 0.000000
[3] =  0.000000 + j 0.000019
[4] =  0.000000 + j 0.000000
[5] =  0.000000 - j 0.000019
[6] =  0.000000 + j 0.000000
[7] = -0.000000 + j 3.999981

z :
[0] = 0.000000
[1] = 5.656800
[2] = 8.000000
[3] = 5.656800
[4] = 0.000000
[5] = -5.656800
[6] = -8.000000
[7] = -5.656800

This shows that the output of the iFFT has not been multiplied by 1/N. Now while his results in a different solution to Matlab, it also makes sense for real-time systems.
In a real-time system there are two considerations :

  1. In floating point systems, scaling can be left until the end of all of the processing and applied to give the correct result for the applications
  2. In fixed point systems, scaling is fundamental to achieving the best signal to noise performance for the algorithm, without overflowing the fixed point number system

If you do want to scale the SigLib output to match that of Matlab and Octave it is as simple as :

    SDA_Multiply (z,                        // Pointer to source array
                  SIGLIB_ONE / FFT_LENGTH,  // Inverse FFT length
                  z,                        // Pointer to destination array
                  FFT_LENGTH);              // Dataset length

And, of course, if this is a fixed point number system you can just right shift by log2(N) to achieve the same, which is very efficient.

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Saturday 20 January 2018

Compiling PortAudio with Cygwin/GCC

In this post : http://blog.numerix-dsp.com/2018/01/notes-on-using-cygwin-for-dsp.html. I described using Cygwin and GCC for developing Digital Signal Processing algorithms.

I like to use PortAudio for audio I/O and testing audio signal processing algorithms, particularly using the XMOS xCORE-200 Multichannel Audio Platform : https://www.xmos.com/support/boards?product=18334.

Here are my list of instructions for compiling and using PortAudio with Cygwin/GCC.

To build PortAudio using Cygwin/GCC, execute the following commands in the Cygwin command prompt (Note, the default configure/make creates a .dll library. This works perfectly well but I prefer static linking because then I do not have to worry about locating the .dll file) :

cd /cygdrive/c/portaudio_v19
chmod +x configure
./configure --enable-static --disable-shared --with-winapi=wmme,wasapi,wdmks
make

To get a list of the supported APIs, use the following command :

./configure --help

The results are :

--with-winapi           Select Windows API support
                          ([wmme|directx|asio|wasapi|wdmks][,...]) [wmme]

Now to build an example in a DOS or Cygwin command prompt (e.g. C:\portaudio_v19\examples\paex_sine.c) use the following command line :
gcc paex_sine.c -Wall -Wno-main -Wno-unused-value -std=c99 -I ../include -L ../lib/.libs -l portaudio -o paex_sine.exe -lrt -lwinmm -mthreads

pa_devs is a really useful utility for listing all the audio interfaces :
gcc pa_devs.c -Wall -Wno-main -Wno-unused-value -std=c99 -I ../include -L ../lib/.libs -l portaudio -o pa_devs.exe -lrt -lwinmm -mthreads

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Notes On Using Cygwin For DSP Development

Many companies I work with have corporate policies regarding the use of Windows OS so I usually develop application code in this OS. I have used a variety of compiler tools over the years but I have been increasingly using GCC under Cygwin for my DSP development work.

Over the past few years I have found the Cygwin/GCC/SigLb combination to be both powerful and reliable.

In order to assist customers setup a Cygwin/GCC/SigLb development environment I get the customer to install the base cygwin installation then run the following batch file :

rem Batch file for configuring Cygwin/GCC/SigLb development environment

rem Modify these environment variables

set CYGWIN_ROOT_TEMP=C:\cygwin64
set SIGLIB_ROOT_TEMP=/cygdrive/c/siglib

rem Do not modify below this line

setx CYGWIN_HOME %CYGWIN_ROOT_TEMP%
setx PATH "%PATH%;%CYGWIN_ROOT_TEMP%\bin"
setx PATH "%PATH%;C:\Program Files\gnuplot\bin;C:\siglib\Examples\FileIO"

setx C_INCLUDE_PATH %SIGLIB_ROOT_TEMP%/include:%SIGLIB_ROOT_TEMP%/nhl:%SIGLIB_ROOT_TEMP%/gnuplot_c/src
setx LIBRARY_PATH %SIGLIB_ROOT_TEMP%/lib/GCC_Win:%SIGLIB_ROOT_TEMP%/nhl:%SIGLIB_ROOT_TEMP%/gnuplot_c/src

rem Install required some packages (and some extras that are useful for development)

%CYGWIN_ROOT_TEMP%\setup-x86_64.exe --no-desktop --no-shortcuts --no-startmenu --quiet-mode --root %CYGWIN_ROOT_TEMP% --packages gcc-core gcc-g++ gccmakedep gdb git gitk gedit gedit-code-assistance gedit-devel gedit-plugins grep make cmake nano splint wget xorg-server xinit grep openssh diff patch

I use the Gnuplot/C (https://sourceforge.net/projects/gnuplotc/) interface to Gnuplot for plotting DSP graphical results. Gnuplot/C pipes the data from the application to Gnuplot and while Gnuplot can be installed in Cygwin I find that a native Windows installation is more efficient and there are no limitations when piping data from the Cygwin environment to the native Windows. More details on installing Gnuplot are available in this blog post : http://blog.numerix-dsp.com/2014/06/gnuplot-installation-under-windows.html.

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Wednesday 10 January 2018

Should I MAC Or Should I MSUB (With Apologies To The Clash)

When implementing FIR filters the coefficients are all in a linear array so the task of importing the coefficients into an application is relatively straight forward.

Importing IIR coefficients into an application, however, is quite different and there are several traps than can cause the application to fail.

The following diagram shows the flow diagram of a direct form I IIR biquad :


All digital filter design programs will return a single or multi-dimensional array along the lines of the following :

int pIIRCoeffs[NUMBER_OF_FILTER_STAGES * NUMBER_OF_COEFFS_PER_BIQUAD] = {
    Coefficients for Biquad #1,
    Coefficients for Biquad #2,
    Coefficients for Biquad #3
};

There are two traps to consider when using the coefficients from a digital filter design program.

  1. The sign of the feedback coefficients may or may not be negated, in which case you may need to negate the coefficients yourself.
  2. There is no international standard for which set of coefficients should be notated an or bn. You should check the documentation of your design tools because there are always : 3 feedforward coefficients and 2 feedback coefficients. You may need to re-order the feedforward and feedback coefficients in your array.
Point 1. raises further issues with the implementation :


  1. Negating the feedback coefficients allows the use of the Multiply-Accumulate (mac) instruction, which is available on all DSPs and many microprocessors and microcontrollers.
  2. Not negating the feedback coefficients will require a multiply followed by a subtract. Nearly all DSPs and some microprocessors and microcontrollers implement a Multiply-Subtract (msub) instruction. If your chosen device does not implement msub then the multiply and subtract operations will be separated leading to slower performance. In this case it would be better to negate the coefficients and use a code implementation that uses the mac instruction. Many digital filter design programs, including Numerix' Digital Filter Plus (http://www.numerix-dsp.com/dfplus/) provide an option to pre-negate the coefficients, which allows the use of the mac instruction. The SigLib DSP library (http://www.numerix-dsp.com/siglib.html) includes functions to implement either format.

If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.

Evaluate The Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/

Tuesday 9 January 2018

Software For Editing Sampled Waveforms

I have talked before, in this blog, about using the excellent Audacity (http://audacity.sourceforge.net) for DSP applications.

When editing sampled data files and viewing them in the time or frequency domain then Audacity can be very powerful.

While Audacity does support some scripting functionality (https://manual.audacityteam.org/man/scripting.html), I often find that Sox (http://sox.sourceforge.net/) applications for pre-conditioning the audio files, extracting a section of audio or shortening a .wav file then I will typically use sox from a script.

On the other hand, if I want to do something more complex such as visually aligning the data in two files then Audacity is much more convenient for a small number of files.

For aligning a larger group of files I would typically do this using a correlator but that is a subject for a future blog post.

Evaluate the Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/.

New Version Of The SigLib DSP Library Released

Version 8.60 is the latest version of the SigLib DSP library and is available now from http://www.numerix-dsp.com/siglib.html.

Additional functionality includes new envelope detectors, new FIR and IIR filter architectures, microphone array beamformer and FFT functions.

To evaluate the Numerix-DSP Libraries : http://www.numerix-dsp.com/eval/.