nsound-0.9.0-userguide
TRANSCRIPT
-
8/12/2019 nsound-0.9.0-userguide
1/77
Nsound Users GuideRelease 0.9.0
Nick Hilton
2013-12-24 21:11:34.080274
-
8/12/2019 nsound-0.9.0-userguide
2/77
-
8/12/2019 nsound-0.9.0-userguide
3/77
CONTENTS
1 Introduction 31.1 What is Nsound? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Building and installing Nsound . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.3 Getting Started Using Nsound . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2 Nsound Basics 132.1 Nsound Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.2 Bu ff er Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.3 AudioStream Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.4 Wavele IO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.5 Basic Manipulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.6 Plotting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3 Nsound Audio Playback 253.1 Audio Backends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.2 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.3 Know Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4 Nsound Instruments 294.1 Bass Guitar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.2 Clarinet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.3 Kick Bass Drum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.4 BD01 Drum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.5 Hat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6 Pipe Organ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.7 Slide Flute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5 Nsound Generators 335.1 The Generator Draw Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335.2 The Sine Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405.3 The Sawtooth Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.4 The Square Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
i
-
8/12/2019 nsound-0.9.0-userguide
4/77
6 Nsound Filters 476.1 FIR Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476.2 FIR Filter Frequency Response . . . . . . . . . . . . . . . . . . . . . . . . . . . 486.3 FIR Filter Frequency Response vs Filter Order . . . . . . . . . . . . . . . . . . . 506.4 IIR Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.5 IIR Filter Frequency Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536.6 IIR Filter Frequency Response vs Filter Order . . . . . . . . . . . . . . . . . . . 556.7 IIR Filter Frequency Response vs Ripple Percent . . . . . . . . . . . . . . . . . . 57
7 Nsound FFT 617.1 Using a Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
8 Nsound Stretcher 67
Index 73
ii
-
8/12/2019 nsound-0.9.0-userguide
5/77
Nsound Users Guide, Release 0.9.0
Warning: This Users Guide is still a work in progress; some of the material is not organized,and several aspects of Nsound are not yet covered in su fficient detail.
This guide is intended as an introductory overview of Nsound and explains how to install andmake use of the most important features of Nsound. For detailed reference documentationof the functions and classes contained in the package, see the Doxygen documentation on thensound.sourceforge.net website.
Note: Nsound is open source software, the developers continually work on improving the libraryand documentation and encourage others interested to contribute. For information on how to doso, please contact Nick Hilton at weegreenblobbie_yahoo_com. Thanks!
CONTENTS 1
http://nsound.sourceforge.net/doxygen/index.htmlhttp://nsound.sourceforge.net/doxygen/index.html -
8/12/2019 nsound-0.9.0-userguide
6/77
Nsound Users Guide, Release 0.9.0
2 CONTENTS
-
8/12/2019 nsound-0.9.0-userguide
7/77
CHAPTER
ONE
INTRODUCTION
1.1 What is Nsound?
Nsound is a C ++ library and Python module for audio synthesis featuring dynamic digital lters.Nsound lets you easily shape waveforms and write to disk or plot them.
In Nsound, all audio data is represented by 64-bit oating point numbers between -1.0 and 1.0. Itis easy to scale the data and adjust the volume by multiplying the audio data by a percentage, anumber between 0.0 and 1.0. The audio data is is only converted to 8-bit, 16-bit, 24-bit, 32-bit or64-bit when it is written to the disk with the Wavele class.
The core of Nsound is the Bu ff er class. Memory is dynamically allocated and frees the userfrom worrying about bu ff er sizes. All the mathematical operators are overloaded to allow intuitiveexpressions.
Generators produce oscillations of the waveform stored in them. Generators can produce a singlefrequency of the waveform held in them, or can dynamicly change frequency, just draw a line thatrepresents frequency and pass it into the generator.
A collection of IIR & FIR lters are also included. When creating lters, the cuto ff frequency isspecied in Hz. The lters are also real-time, meaning they keep track of their internal state andfor each audio sample passed in, an audio sample is returned.
Beautiful plots can be easily created if your platform has the Python Matplotlib package installed.Most of the Nsound classes have their own plot methods.
This Users Guide will specify code snippets written in Python. The C ++ code is nearly identical.
For specic C ++ reference, view the Doxygen generated documentation available on the Nsoundsourceforge website .
3
http://nsound.sourceforge.net/doxygen/index.htmlhttp://nsound.sourceforge.net/doxygen/index.html -
8/12/2019 nsound-0.9.0-userguide
8/77
Nsound Users Guide, Release 0.9.0
1.2 Building and installing Nsound
1.2.1 Binary installers
In most cases, the best way to install Nsound on your system is by using an installable binaryPython package for your operating system.
Windows
As of nsound-0.9.0, support for building with Vistual Studio 2010 + on 64-bits is now supported.Building on 32-bits is no longer tested as I no longer have access to a 32-bit Windows.
Linux
No binary packages are currently available. But your Linux box in most cases already has all thetools needed to build and install Nsound.
Mac OS X
No binary packages are currently available. But your OS X box in most cases already has all thetools needed to build and install Nsound.
1.2.2 Building from source
A general overview of building Nsound from source is given here, with detailed instructions forspecic platforms given separately.
Prerequisites
Building Nsound requires the following software installed:
1. Python 2.7.x
On Debian and derivative (Ubuntu): python
On Windows: the o fficial 64-bit Python installer at www.python.org is enough
On Mac OSX: I highly recommend the MacPorts package manager to install thelatest versions of Python, Numpy and Matplotlib www.macports.org .
2. Scons
4 Chapter 1. Introduction
http://www.python.org/http://www.macports.org/install.phphttp://www.macports.org/install.phphttp://www.python.org/ -
8/12/2019 nsound-0.9.0-userguide
9/77
Nsound Users Guide, Release 0.9.0
Nsound uses this execellent build system, www.scons.org .
On Windows: a 64-bit self-installer is not provied (as of 2013-12-24), youll haveto download the source .Zip archive and do:
python setup.py bdist_wininst
and install it by running the dist / scons*.exe le.
3. A C ++ compiler
To build Nsound and the Python extension module, youll need a C ++ compiler.
On Windows: youll need to install Visual Studio 2010 + (2012 Express works).
On Mac OS X: You will need to install XCode.
Optional Prerequisites
1. SWIG
To build the Python module, SWIG generates the Python wrapper code.
www.swig.org
On Windows: youll download and unzip to C:\ .
2. Matplotlib (Numpy, dateutil, pyparsing, six)
For creating pretty plots, Matplotlib is used.
Numpy and python-dateutil are a prerequisites for Matplotlib.
Numpy: numpy.scipy.org
Matplotlib: matplotlib.sourceforge.net
On Windows: use the prebuilt 64-bit binaries from here: Unofficial Win-dows Binaries for Python Extension Packages
3. AO or PortAudio
To enable audio playback through the soundcard, Nsound can use libao or libpor-taudio.
AO: www.xiph.org / ao
PortAudio: www.portaudio.com
On Windows, these have already been statically built and provided.
1.2. Building and installing Nsound 5
http://www.scons.org/http://www.swig.org/http://numpy.scipy.org/http://matplotlib.sourceforge.net/http://www.lfd.uci.edu/~gohlke/pythonlibs/http://www.lfd.uci.edu/~gohlke/pythonlibs/http://www.lfd.uci.edu/~gohlke/pythonlibs/http://www.lfd.uci.edu/~gohlke/pythonlibs/http://www.xiph.org/aohttp://www.xiph.org/aohttp://www.xiph.org/aohttp://www.portaudio.com/http://www.portaudio.com/http://www.xiph.org/aohttp://www.lfd.uci.edu/~gohlke/pythonlibs/http://www.lfd.uci.edu/~gohlke/pythonlibs/http://matplotlib.sourceforge.net/http://numpy.scipy.org/http://www.swig.org/http://www.scons.org/ -
8/12/2019 nsound-0.9.0-userguide
10/77
Nsound Users Guide, Release 0.9.0
Testing that all Matplotlib dependancies are met
Usually this is only a problem for the Windows platform, since Linux and MacPorts download andinstall prerequisite automatically.
1. Start a Python Shell and import matplotlib:>>> import matplotlib>>> # Try to import pylab >>> from matplotlib import pylab>>> # Try to plot something >>> pylab . plot([ 1, 2 , 3, 4], "bo-" )>>> pylab . show()
As you run into missing packages, donload and install them. Most of them are:
Numpy
dateutil
six
pyparsing
1.2.3 Compiling the C++ Library
1. Uncompress the Nsound archive:
$ tar xfz nsound-0.9.0.tar.gz
2. Execute the SCons tool:
cd nsound-0.9.0scons
SCons will query your computer for specic information about the build environment and generatea few les. It will then proceed to build the Nsound library and examples.
To get help with scons, do:
$ scons --help
scons: Reading SConscript files ...Building with 4 threadsscons: done reading SConscript files.
nsound-0.9.0 SCons Help
usage: scons [OPTIONS] [TARGETS] ...
6 Chapter 1. Introduction
-
8/12/2019 nsound-0.9.0-userguide
11/77
Nsound Users Guide, Release 0.9.0
Local Options:
--extra-warnings Adds extra warning flags to CXXFLAGS--disable-64 Disables float64 type, uses float32 instead--disable-libao Disables the libao AudioBackend
--disable-libportaudio Disables the libportaudio AudioBackend--enable-cuda Enables Cuda accelerated functions and linking--disable-openmp Disables OpenMp accelerated functions and
linking--disable-python Disables the use of matplotlib via Python, only
applies to C++ lib--help Prints this help message--static Builds a static C++ lib--prefix=PREFIX Sets the install prefix for programs and
libraries--config-debug Prints lots of debug messages during scons
configuration tests--V, --verbose Shows full compiler command output
Targets:
html Generate the Doxyfile to create the Doxygen htmlfiles
lib Just build libNsoundinstall Installs programs from src/bin to bindir, also
instals libNsound to libdir, Nsound includedirnot yet implemented (sorry).
release Creates a source archive namednsound-0.9.0.tar.gz
test Builds the unit test programs in src/test Perform actions that only result in the object_file Perform actions that only result in the program
Examples:
# Update the doxygen config file$ scons src/Doxyfile
# Update only one program $ scons src/examples/stretcher
# Create the Python builder script$ scons setup.py
Use scons -H for help about command-line options.
1.2. Building and installing Nsound 7
-
8/12/2019 nsound-0.9.0-userguide
12/77
Nsound Users Guide, Release 0.9.0
On Windows: Compiling Nsound From The Command Line
On Windows, rather than muck around with the Systems PATH environment variables, I recom-mend creating a .BAT le that will insert paths into the environment.
1. Save this le to your doesktop windows_env64.bat2. Create a shortcut to the le windows_env64.bat , edit the shortcut so the target line reads
like this:
cmd /k C:\Users\USERNAME\Desktop\windows_env64.bat.bat
replacing USERNAME with your username.
3. Modify the shortcut startup directory to be located in the nsound directory, this way youwont have to cd to it all the time.
4. Double click the shortcut to open a DOS box with Visual Studio, Python, and SCons in the
path, so building Nsound becomes as simple as:C:\Users\USERNAME\Documents\nsound> scons
On Windows: Compiling Nsound C++ library Using Visual Studio
Before trying to compile Nsound with Vistual Studio, ensure that Python and SCons have beeninstalled. There are Visual Studio build steps that will execute scons to generate some les.
Next, examine the le msvs\properties.props to ensure the path to Python is correct, thedefault is C:\Python27 .
A Visual Studio 2010 + solution le is provide in msvs\nsound.sln . Debug builds wont link with Python because the debug library python27_d.lib is not provided, but isnt needed if youredebugging Nound C ++ code.
Cygwin Notes
If you run into an error message that looks something like:
python 6140 C:\cygwin\bin\python.exe: *** fatal error - unable to remap \\?\C:\cygwin\lib\pyth
You will need to rebase your Cygwin installation. To do so follow these steps:
1. Close all Cygwin programs that may be using the cygwin.dll
2. Ensure the Cygwin package called rebase is installed using the setup.exe program
3. Start a Windows DOS box (not a Cygwin shell)
4. Start an ASH shell, then run the rebaseall command by executing:
8 Chapter 1. Introduction
-
8/12/2019 nsound-0.9.0-userguide
13/77
Nsound Users Guide, Release 0.9.0
C:\> C:\cygwin\bin\ash.exe$ cd /bin$ ./rebaseall
1.2.4 Compiling the Python Module
Note: SWIG must be installed to generate the Python interface.
1. Try compiling the C ++ library rst to ensure SCons and the C ++ compiler are working (seestep 2 above in Compiling the C ++ Library ).
2. Generate the Python build script by executing:
scons setup.py
3. Build and install the Python module for a single user :
python setup.py install --user
4. Or build and install the Python module system wide :
sudo python setup.py install
5. Or build the Windows self-installer (Windows only ):
python setup.py bdist_wininst
6. Test the Python module:
import Nsound as nsb = ns . Buffer()print b
You should see the text:
Nsound.Buffer holding 0 samples
1.2.5 Linking With A Python Installed In A Non-Standard Location
Sometimes a custom built Python is installed in a non-standard location, for example:
/usr/local/python2.7
You will need to install scons to this non-stanard location, then just run scons with this non-standardpython:
1.2. Building and installing Nsound 9
-
8/12/2019 nsound-0.9.0-userguide
14/77
Nsound Users Guide, Release 0.9.0
/usr/local/python2.7/bin/scons
The SCons build environment will ask Pythons distutils module for the location of the in-clude directory and dynamic library paths. This should get done automatically. A SConstool was added to brute-force check the distutils build variables to locate these paths,site_scons/site_tools/ImportPythonConfig.py . To enable some extra debug messages,try using the --config-debug switch with scons:
$ scons --config-debug
Please report any problems you are having to Nick.
Python Errors
Sometime everything above goes well, SCons nds the libraries, compiles and links everything
ne, but at runtime you may run into other errors.
Matplotlib Backend Not Set
You may see a message like:
Traceback (most recent call last):File "/usr/local/python2.7/lib/python2.7/site-packages/matplotlib/backends/__init__.py", l
fname = frame.f_back.f_code.co_filenameAttributeError: NoneType object has no attribute f_codesrc/Nsound/Plotter.cc:171: failed to call python pylab.show()
This is due to the Matplotlib Backend not being set. So set a default backend edit the le matplotli-brc , and set the following:
backend : BACKEND
and replace BACKEND with something like GTKAgg, GTKCairo, CocoaAgg, MacOSX, QtAgg,WXAgg. The choice depends on the backends that are installed. To test if a specic backend isinstalled do:
>>> import matplotlib>>> matplotlib . use( "GTKAgg" ) # Specify specific backend >>> import matplotlib.pylab>>> pylab . plot([ 1 , 2, 3, 4, 3, 2 , 1])>>> pylab . show() # Plot will appear if you selected a working GUI backend >>> pylab . savefig( "somefile.png" ) # Replace png with pdf or svg to ... # to test a file only backend
You should either see a gure window show up after the show() call or a lename written to thelocal directory after the saveg() call.
10 Chapter 1. Introduction
-
8/12/2019 nsound-0.9.0-userguide
15/77
Nsound Users Guide, Release 0.9.0
1.3 Getting Started Using Nsound
1.3.1 Using The Nsound Python Module
After installing the Nsound Python module, you can start playing with the examples. Downloadthe Nsound source code or check out the subversion tag:
$ svn co https://nsound.svn.sourceforge.net/svnroot/nsound/tags/nsound-0.9.0
Next, modify one of the examples in src / examples, then execute the example:
$ python example1.py
and listen to the wavele written out or look at the plots created.
You can also use the module in Python interactively:
>>> import Nsound as ns>>> b = ns . Buffer()>>> b
-
8/12/2019 nsound-0.9.0-userguide
16/77
Nsound Users Guide, Release 0.9.0
SCons looks for a special le called SConstruct that serves as the master Makele that tellsSCons how to build everything. Nsounds SConstruct le is located in the root of the archive.
The Nsound C ++ library and examples are compiled by default when you invoke scons withoutany arguments:
cd nsound-0.9.0scons
Sopose you are modifying one of the examples and wish to recompile it, you could issue scons inthe root and it will recompile everything that needs to be rebuilt. Now suppose you want work inthe src / example directory. Running SCons in this directory results in the following error message:
scons: *** No SConstruct file found.File "/usr/lib/scons/SCons/Script/Main.py", line 858, in _main
This is because Nsound only contains one SConstruct le, and it only lives in the root of the
archive. This is a common scenario and so the folks that make SCons include a command lineswitch to tell it to look else where for the SConstruct le. So now try this:
scons - U
This will tell scons to search up the directory structure to search for the SConstruct le.
You can also tell SCons to build a specic target. Suppose you are in the examples directory andmodied example2.cc. You may have changes in other example les but you only want to compileexample2.cc. You can specify the target like so:
scons -U example2
Or if you are on Windows:
scons -U example2.exe
12 Chapter 1. Introduction
-
8/12/2019 nsound-0.9.0-userguide
17/77
CHAPTER
TWO
NSOUND BASICS
2.1 Nsound Data Types
When writing new features for Nsound, C ++ typedefs are used to ensure the same bit width is usedon all platforms. To see how these types are dened, look at the le src / Nsound / Nsound.h afterrunning SCons.
If you are using the Python module, you wont need to know anything about these data types.
Type Descriptionboolean The C ++ bool typeint8 Integer (-128 to 127)int16 Integer (-32768 to 32767)int32 Integer (-2147483648 to 2147483647)
int64 Integer (9223372036854775808 to 9223372036854775807)oat32 Single precision oat: sign bit, 8 bits exponent, 23 bits mantissaoat64 Double precision oat: sign bit, 11 bits exponent, 52 bits mantissauint8 Unsigned integer (0 to 255)uint16 Unsigned integer (0 to 65535)uint32 Unsigned integer (0 to 4294967295)uint64 Unsigned integer (0 to 18446744073709551615)
2.2 Buffer Creation
A Buff er holds audio samples at discrete sample periods. The Bu ff er object knows nothing abouttime, endianness or bit precision. It is a generic container of oating point data.
There are 3 general ways to create an Nsound Bu ff er:
1. Creating an empty Bu ff er
2. Call ones(), rand() or zeros()
13
-
8/12/2019 nsound-0.9.0-userguide
18/77
Nsound Users Guide, Release 0.9.0
3. Reading a wavele from disk
2.2.1 Creating An Empty Buffer
Call the constructor:
import Nsound as nsb = ns . Buffer()
The new Bu ff er b is empty. Calling the getLength() method will return 0.
The underlying data structure that is held by the Bu ff er class is a std::vector. One can preallocatememory when creating a bu ff er by specify the number of samples to preallocate:
b = ns . Buffer( 1024 )
The new Bu ff er b is empty, even though memory was preallocated. Calling the getLength() methodwill return 0.
In general, you dont need to worry about preallocating memory. It is meant to be useful whenimplementing new features in Nsound when the size of Bu ff ers are already known.
2.2.2 Call Ones, Rand or Zeros
The Bu ff er class includes some convience functions for creating Bu ff ers that are lled with oness,random numbers or zeros:
Buffer. ones ( n_samples )Buffer. rand ( n_samples )
Buffer. zeros ( n_samples )
Example usage:
import Nsound as nsb1 = ns . Buffer . ones( 10 )b2 = ns . Buffer . rand( 10 )b3 = ns . Buffer . zeros( 10 )
In the example above, 10 samples were stored in the created Bu ff ers.
2.2.3 Reading A Wavele From Disk
A Buff er can be created from a wavele:
14 Chapter 2. Nsound Basics
-
8/12/2019 nsound-0.9.0-userguide
19/77
Nsound Users Guide, Release 0.9.0
b = ns . Buffer( "california.wav" )
The new Bu ff er b will contain all the samples in california.wav. If the wavele has more thanone channel, only the rst channel is read and stored in the new Bu ff er.
The waveles data will be converted into oat64 with a range of (-1.0, 1.0.).
2.3 AudioStream Creation
An AudioStream is a container that holds Bu ff ers, it also stores a sample rate, providing informa-tion about time. It is meant to easily manipulate multiple channels of audio at the same time. MostNsound functions that operate on Bu ff ers also operate on AudioStreams.
There are 3 general ways to create an AudioStream:
1. Creating an empty AudioStream2. Call ones(), rand() or zeros()
3. Reading a wavele from disk
2.3.1 Creating An Empty AudioStream
Call the constructor:
import Nsound as ns
a = ns . AudioStream()
The default constructor sets the sample rate to 44100.0 and a single channel. The new AudioStreama is empty. Calling the getLength() method will return 0. Calling the getDuration() method willreturn 0.0.
To specify the sample rate:
a = ns . AudioStream( 44100.0 )
This will create a new AudioStream with a sample rate of 44.1 kHz and a single channel. To createa stereo AudioStream:
a = ns . AudioStream( 44100.0 , 2)
The is no limit to the number of channels an AudioStream can have. In practice, the number of channels and their duration will be limited to the amount of memory your computer has.
The underlying data structure that is held by the AudioStream class is a std::vector of Bu ff er ob- jects. One can preallocate memory when creating an AudioStream by specify the number of sam-ples to preallocate:
2.3. AudioStream Creation 15
-
8/12/2019 nsound-0.9.0-userguide
20/77
Nsound Users Guide, Release 0.9.0
a = ns . AudioStream( 44100.0 , 2, 1024 )
The new AudioStream a is empty, even though memory was preallocated. Calling the getLength()method will return 0, calling getDuration() will return 0.0.
In general, you dont need to worry about preallocating memory. It is meant to be useful whenimplementing new features in Nsound when the size of AudioStreams are already known.
2.3.2 Call Ones, Rand or Zeros
The Bu ff er class includes some convience functions for creating Bu ff ers that are lled with oness,random numbers or zeros:
AudioStream. ones ( sample_rate , n_channels , n_samples )
AudioStream. rand ( sample_rate , n_channels , n_samples )
AudioStream. zeros ( sample_rate , n_channels , n_samples )
Example usage:
import Nsound as nsa1 = ns . AudioStream . ones( 44100.0 , 2, 1.0 )a2 = ns . AudioStream . rand( 44100.0 , 2, 1.0 )a3 = ns . AudioStream . zeros( 44100.0 , 2, 1.0 )
In the example above, 44100 samples (1 second) were stored in 2 channels.
2.3.3 Reading A Wavele From Disk
An AudioStream can be created from a wavele:
a = ns . AudioStream( "california.wav" )
The new AudioStream a will contain all the samples in california.wav. If the wavele has morethan one channel, all channels are read and stored in the new AudioStream. The waveles samplerate is also read and stored in the AudioStream.
The waveles data will be converted into oat64 with a range of (-1.0, 1.0.).
2.4 Wavele IO
Nsound includes a simple Wavele class that can read RIFF waveles that are PCM encoded. Thisis a very basic wavele format. Nsound currently does not support any other audio formats, butthere are plenty of other free tools on the web that can convert audio formats to PCM waveles.
16 Chapter 2. Nsound Basics
-
8/12/2019 nsound-0.9.0-userguide
21/77
Nsound Users Guide, Release 0.9.0
2.4.1 Reading Waveles
As seen in previous sections, a wavele can be read by passing its lename to the Bu ff er or Au-dioStream constructor:
import Nsound as ns
b = ns . Buffer( "california.wav" )a = ns . AudioStream( "california.wav" )
Nsound has also overloaded the left shift operator, concatenation from waveles is easy:
import Nsound as ns
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
22/77
Nsound Users Guide, Release 0.9.0
a . writeWavefile( "california-32bit.wav" )
Nsound has also overloaded the right shift operator for writing waveles, the example above canbe rewritten as:
import Nsound as ns
a = ns . AudioStream( "california.wav" )
ns . Wavefile . setDefaultSampleSize( 32 )
a >> "california-32bit.wav"
Nsound will write waveles using integer data types by default. This can be changed to oatingpoint.
2.4.3 Floating Point Waveles
Warning: Few programs know how to read the IEEE oating point format. Audacity 1.3.12is able to read mono oating point formats, but does not seem to be able to read multi channelles.
Note: Since the data is stored as oating point, there is no need to normalize the data rst.
Nsound can read and write waveles that store their samples in IEEE oating point format. Towrite les using this format, call:
Wavefile. setIEEEFloat ( ag )
And set the ag to True. The Wavele sample size must be set to 32 or 64.
2.4.4 Resampling Waveles
Sometimes a wavele wont be at the sample rate that we wish it were. For example, you down-loaded a sample sound but it is not at the sample rate of your project.
With Nsound its easy to resample the le to the sample rate you need:
import Nsound as ns
a = ns . AudioStream( "wav_at_16KHz.wav" )
a . resample2( 48000.0 )
18 Chapter 2. Nsound Basics
-
8/12/2019 nsound-0.9.0-userguide
23/77
Nsound Users Guide, Release 0.9.0
a >> "wav_at_48KHz.wav"
The Python script below can be used on the command line to change a waveles sample rate:
#! /usr/bin/env python
import Nsound as ns
from optparse import OptionParser
parser = OptionParser(usage = "resample target_sample_rate input.wav output.wav" )
(options, argv) = parser . parse_args()
argc = len (argv)
if argc != 3:raise RuntimeException( "Expecting 3 arguments!" )
target = float (argv[ 0])f1 = argv[ 1]f2 = argv[ 2]
print "Reading %s" % f1
a1 = ns . AudioStream(f1)
source = a1 . getSampleRate()
print "source: %d " %(source)print "target: %d " %(target)
ratio = target / source
print "ratio: %f " %(ratio)
print "Resampling ..."
a2 = a1 . getResample(ratio)a2 . setSampleRate( int (target))
print "Writing %s" % f2
a2 >> f2
2.4. Wavele IO 19
-
8/12/2019 nsound-0.9.0-userguide
24/77
Nsound Users Guide, Release 0.9.0
2.5 Basic Manipulations
AudioStream and Bu ff er objects have nearly all of their mathematical operators overloaded. It iseasy to manipulate the data they contain. Every operation that can be done on a Bu ff er can be done
on an AudioStream. In the following examples, only the Bu ff er case will be demonstrated, but itcan easily be done to an AudioStream as well.
2.5.1 Concatenation
After creating an empty Bu ff er, one can insert samples into it with concatenation:
import Nsound as nsb = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
25/77
Nsound Users Guide, Release 0.9.0
print b. toList()# [2.0, 3.0, 6.0, 7.0, 8.0, 9.0]
b *= 2.0print b. toList()# [4.0, 6.0, 12.0, 14.0, 16.0, 18.0]
b /= 3.0print b. toList()# [1.3333, 2.0, 2.6666, 4.6666, 5.3333, 6.0]
2.5.3 Vector Math
Nsound also allows element-wise math between two Bu ff ers. Unlike other packages such as
Numpy or Matlab, the Buff
ers dont have to be the same length:import Nsound as ns
b1 = ns . Buffer()b1
-
8/12/2019 nsound-0.9.0-userguide
26/77
Nsound Users Guide, Release 0.9.0
# Products
b3 = b1 * b2
print b3 . toList()# [0.0, 1.0, 1.0]
b3 = b2 * b1
print b3 . toList()# [0.0, 1.0, 1.0, 1.0]
# Quotients
b3 = b1 / b2
print b3 . toList()# [1e+20, 1.0, 1.0]
b3 = b2 / b1
print b3 . toList()# [0.0, 1.0, 1.0, 1.0]
2.6 Plotting
Nsound uses the wonderful Matplotlib package for making plots. To do this, a simple C ++ classcalled Plotter wraps some of the Python C-API so that the C ++ libNsound library can make callsinto the Matplotlib classes to make plots.
22 Chapter 2. Nsound Basics
-
8/12/2019 nsound-0.9.0-userguide
27/77
Nsound Users Guide, Release 0.9.0
In the Python module, the Plotter class make calls into the Python Matplotlib module.
If you are using the C ++ library and the Matplotlib C-API was found, plotting will be enabled. If you are using the Python module and Matplotlib is installed, plotting will be enabled.
Note: Plots will not pop up by default with the C ++ or non-interactive Python code. For C ++ , acall to Plotter::show() will render the plots to the screen. With the Python module, a call to eithermatplotlib.pylab.show() or Nsound.Plotter.show() will display the plots.
Note: You will not see calls to Plotter.show() in this Users Guide, the plots are generated withinline Python code and are saved to disk.
Note: On MacOSX, if you are using the MacPorts package manager to install Python, Numpy,and Matplotlib in / opt / local, you will need to set the default Matplotlib backend. To do so edit thele ~ / .matplotlib / matplotlibrc and add a line that reads backend : MacOSX.
Once you start manipulating your Bu ff ers and AudioStreams, it is easy to see the e ff ect by plottingthem:
import Nsound as ns
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
28/77
Nsound Users Guide, Release 0.9.0
a[ 0] = ba[ 1] = b. getReverse()a . plot( "Figure 2" )
# Your code needs to call the show()# method to make the plots show up.
# ns.Plotter.show()
0 . 0 0 . 5 1 . 0 1 . 5
2 . 0 2 . 5 3 . 0
. 0
. 5
. 0
. 5
. 0
. 5
. 0
F i g u r e 1
0 . 0 0 . 5 1 . 0 1 . 5
2 . 0 2 . 5 3 . 0
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
. 5
. 0
F i g u r e 2
0 . 0 0 . 5 1 . 0 1 . 5
2 . 0 2 . 5 3 . 0
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
. 5
. 0
24 Chapter 2. Nsound Basics
-
8/12/2019 nsound-0.9.0-userguide
29/77
CHAPTER
THREE
NSOUND AUDIO PLAYBACK
As of Nsound-0.8.1, playback through the soundcard is now supported on platforms that have libaoor libportaudio.
Audio playback can be as simple as:
import Nsound as nsa = ns . AudioStream( "california.wav" )a >> ns . AudioPlayback(a . getSamplerate(), a . getNChannels(), 16 )
The Nsound.AudioPlayback constructor:Nsound. AudioPlayback ( sample_rate , n_channels , bits_per_sample )
sample_rate [oat] The number of samples per seconds
n_channels [int] The number of channels, currently on 1 or 2 is supported
bits_per_sample [int] The sample size to convert to before playing it on the sound card, currentlyonly 16 and 32 are supported
25
-
8/12/2019 nsound-0.9.0-userguide
30/77
Nsound Users Guide, Release 0.9.0
Not all combinations of sample_rate , n_channels and bits_per_sample will work. Mostplatforms should work with
sample_rate = 44100
n_channels = 1 , n_channels = 2
bits_per_sample = 16 , bits_per_sample = 32
Other combinations have not been tested.
3.1 Audio Backends
The audio backend to use can be selected. By default, the audio backend is automatically selecetedbased on the backends that were available at compile time in the following order:
1. PortAudio2. AO
3. None
Following the Matplotlib convention, a call to Nsound.use() can select the audio backend to use.
Nsound. use ( backend )
backend [str] The backend to use; currently recognized backends:
1. portaudio or libportaudio
2. ao or libao
The backend must be selected before initializing the AudioPlayback class:
ns . use( "portaudio" )
pb = ns . AudioPlayback( 44100.0 , 2, 16 )
buffer_or_audio_stream >> pb
See src/examples/example1.py and src/examples/example4.py for AudioPlayback exam-
ple usage.
3.2 Limitations
The Nsound.AudioPlayback class is not thread safe, so only one thread can use the class at atime. Only blocking calls are currently implemented, with memory being allocated and oatingpoint numbers being casted to integer types on a call by call basis.
26 Chapter 3. Nsound Audio Playback
-
8/12/2019 nsound-0.9.0-userguide
31/77
Nsound Users Guide, Release 0.9.0
3.3 Know Problems
If you are on Linux and you are using libportaudio, you may see a message like:
bt_audio_service_open: connect() failed: Connection refused (111)bt_audio_service_open: connect() failed: Connection refused (111)
Audio will still be played to the sound card (at least on Nicks Ubuntu 10.04 box.) The errorhappens because Bluetooth is disabled but ALSA is still congured to use Bluetooth services, tox this, remove the bluez-alsa package:
$ sudo apt-get purge bluez-alsa
The error messsage should now go away, but be careful with this solution if you use Bluetoothdevices for audio.
3.3. Know Problems 27
-
8/12/2019 nsound-0.9.0-userguide
32/77
Nsound Users Guide, Release 0.9.0
28 Chapter 3. Nsound Audio Playback
-
8/12/2019 nsound-0.9.0-userguide
33/77
CHAPTER
FOUR
NSOUND INSTRUMENTS
Instruments are classes that provide a common API, their purpose is to provide a foundation of common musical elements for everyone to use.
All Nsound Instruments will provide the following functions:Nsound.Instrument. play ()
Returns:
demo [Nsound.AudioStream] Returns a demo created by the author of the instrument
Nsound.Instrument. play ( duration , frequency )
Parameters:
duration [oat] The duration in seconds of sound to generate
frequency [oat] The frequency of the sound in Hz
Returns:
out [Nsound.AudioStream] Returns the sound of the instrument at the givenfrequency for duration seconds
4.1 Bass Guitar
Based on a physical model written in Csound by Hans Mikelson.
Nsound. GuitarBass ( sample_rate )
sample_rate [oat] The number of samples per seconds
29
-
8/12/2019 nsound-0.9.0-userguide
34/77
Nsound Users Guide, Release 0.9.0
4.2 Clarinet
Based on a physical model written in Csound by Hans Mikelson which was originally based onPerry Cooks physical model.
Nsound. Clarinet ( sample_rate )
sample_rate [oat] The number of samples per seconds
4.3 Kick Bass Drum
Nsound. DrumKickBass ( sample_rate , high_frequency , low_frequency )
sample_rate [oat] The number of samples per seconds
high_frequency [oat] The starting frequency of the drumlow_frequency [oat] The stopping frequency of the drum as its response decays
4.4 BD01 Drum
Simulates a bass drum. Based on a Csound drum.
source: http: // www.csounds.com / istvan / html / drums.html
Nsound. DrumBD01( sample_rate )
sample_rate [oat] The number of samples per seconds
4.5 Hat
Simulates a Hat hit, based on a Csound Hat instrument by Steven Cook.
Nsound. Hat ( sample_rate )
sample_rate [oat] The number of samples per seconds
4.6 Pipe Organ
Based on a Csound Pipe Organ by Hons Mikelson.
Nsound. OrganPipe ( sample_rate )
30 Chapter 4. Nsound Instruments
http://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.htmlhttp://www.csounds.com/istvan/html/drums.html -
8/12/2019 nsound-0.9.0-userguide
35/77
Nsound Users Guide, Release 0.9.0
sample_rate [oat] The number of samples per seconds
4.7 Slide Flute
Based on a physical model written in Csound by Hans Mikelson which was originally based onPerry Cooks physical model.
Nsound. FluteSlide ( sample_rate )
sample_rate [oat] The number of samples per seconds
4.7. Slide Flute 31
-
8/12/2019 nsound-0.9.0-userguide
36/77
Nsound Users Guide, Release 0.9.0
32 Chapter 4. Nsound Instruments
-
8/12/2019 nsound-0.9.0-userguide
37/77
CHAPTER
FIVE
NSOUND GENERATORS
Note: These examples use a small sample rate (between 100 and 1000) to keep the generation of this documentation relitively quick. In practice, higher quality sample rates should be used (44100,
48000, 96000 etc.).
5.1 The Generator Draw Routines
All Nsound Generators include basic drawing functions. Some basic Generator function documen-tation:
Generator ( sample_rate )
Generator. drawDecay ( duration , alpha = 2.0*pi )Generator. drawLine ( duration , y1, y2)
Generator. drawGaussian ( duration , mu, sigma , normalize = True )
Generator. drawFatGaussian ( duration , pass_band_percent = 0.01 )
Generator. drawParabola ( duration , y1, x2, y2, y3)
Generator. drawSine ( duration , frequency )
Generator. drawSine2 ( duration , frequency , phase )
Generator. drawWindow ( duration , window_type )Drawing lines:
import Nsound as ns
g = ns . Generator( 100.0 )
b = ns . Buffer()
33
-
8/12/2019 nsound-0.9.0-userguide
38/77
Nsound Users Guide, Release 0.9.0
b
-
8/12/2019 nsound-0.9.0-userguide
39/77
Nsound Users Guide, Release 0.9.0
0 2 0 4 0 6 0 8 0 1 0 0
. 0
. 2
. 4
. 6
. 8
. 0
E x p o n e n t i a l D e c a y
Drawing Gaussians:
import Nsound as ns
g = ns . Generator( 100.0 )
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
40/77
Nsound Users Guide, Release 0.9.0
0 2 0 4 0 6 0 8 0 1 0 0
. 0
. 2
. 4
. 6
. 8
. 0
A G a u s s i a n C u r v e
0 2 0 4 0 6 0 8 0 1 0 0
. 0
. 2
. 4
. 6
. 8
. 0
A F a t G a u s s i a n C u r v e
Drawing parabolas, note that an AudioStream is used so the x axis has the units of seconds:
import Nsound as ns
from matplotlib import pylab
sr = 1000.0
g = ns . Generator(sr)
36 Chapter 5. Nsound Generators
-
8/12/2019 nsound-0.9.0-userguide
41/77
Nsound Users Guide, Release 0.9.0
########################################################################### # First Parabola
a = ns . AudioStream(sr, 1)a
-
8/12/2019 nsound-0.9.0-userguide
42/77
Nsound Users Guide, Release 0.9.0
0 . 0 0 . 2 0 . 4 0 . 6 0 . 8 1 . 0
T i m e ( s e c )
. 0
. 2
. 4
. 6
. 8
. 0
A P a r a b o l a
0 . 0 0 . 2 0 . 4 0 . 6 0 . 8 1 . 0
T i m e ( s e c )
. 0
. 2
. 4
. 6
. 8
. 0
A n o t h e r P a r a b o l a
Drawing sine waves. The drawSine() and drawSine2() functions use the C ++ std::sin() function togenerate samples. These functions do not use a wavetable, so there will not be any interpolationor aliasing problems that may occur for wavetable oscillator classes that derive from Generator.Some examples:
import Nsound as ns
sr = 1000.0
g = ns . Generator(sr)
38 Chapter 5. Nsound Generators
-
8/12/2019 nsound-0.9.0-userguide
43/77
Nsound Users Guide, Release 0.9.0
########################################################################### # 3 Hz a = ns . AudioStream(sr, 1)a
-
8/12/2019 nsound-0.9.0-userguide
44/77
Nsound Users Guide, Release 0.9.0
0 . 0 0 . 2 0 . 4 0 . 6 0 . 8 1 . 0
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
D y n a m i c F r e q u e n c y
0 . 0 0 . 2 0 . 4 0 . 6 0 . 8 1 . 0
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
D y n a m i c P h a s e
5.2 The Sine Generator
The Sine class is derived from Generator. Some of its documentation:
Sine ( sample_rate )
Sine. generator ( duration , frequency )
It inherits all the draw functions for convience. Lets generate a 3 Hz signal.
40 Chapter 5. Nsound Generators
-
8/12/2019 nsound-0.9.0-userguide
45/77
Nsound Users Guide, Release 0.9.0
import Nsound as ns
s = ns . Sine( 100.0 )
b = ns . Buffer()
b
-
8/12/2019 nsound-0.9.0-userguide
46/77
Nsound Users Guide, Release 0.9.0
0 2 0 4 0 6 0 8 0 1 0 0
. 0
. 5
. 0
. 5
. 0
3 H z W i t h G a u s s i a n E n v e l o p e
0 2 0 4 0 6 0 8 0 1 0 0
. 2
. 0
. 2
. 4
. 6
3 H z W i t h D e c a y i n g E n v e l o p e
The Generator class also allow dynamically changing frequencies. Simply create a Bu ff er to holdfrequency values and pass the Bu ff er to the generate function. Below the frequency will changefrom 1 to 10 back to 1.
import Nsound as ns
s = ns . Sine( 1000.0 )
freqs = ns . Buffer()freqs
-
8/12/2019 nsound-0.9.0-userguide
47/77
Nsound Users Guide, Release 0.9.0
-
8/12/2019 nsound-0.9.0-userguide
48/77
Nsound Users Guide, Release 0.9.0
5.3 The Sawtooth Generator
As you would expect, the Sawtooth Generator draws sawtooths, with the specied number of harmonics.
Sawtooth ( sample_rate , n_harmonics )
Sawtooth. generator ( duration , frequency )
import Nsound as ns
saw = ns . Sawtooth( 100 , 3)
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
49/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0 3 0 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
S a w t o o t h , 1 2 h a r m o n i c s
5.4 The Square Generator
As you would expect, the Square Generator draws square waves, with the specied number of harmonics.
Square ( sample_rate , n_harmonics )
Square. generator ( duration , frequency )import Nsound as ns
square = ns . Square( 100 , 3)
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
50/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0 3 0 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
S q u a r e w a v e , 3 h a r m o n i c s
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0 3 0 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
S q u a r e w a v e , 1 2 h a r m o n i c s
46 Chapter 5. Nsound Generators
-
8/12/2019 nsound-0.9.0-userguide
51/77
-
8/12/2019 nsound-0.9.0-userguide
52/77
Nsound Users Guide, Release 0.9.0
fc The lter cut o ff frequency in Hz.
fc_low The lower lter cut o ff frequency in Hz
fc_high The high lter cut o ff frequency in Hz
6.2 FIR Filter Frequency Response
Frequency responses for FIR lters:
import Nsound as ns
f1 = ns . FilterLowPassFIR( 500.0 , 64 , 100.0 )f2 = ns . FilterHighPassFIR( 500.0 , 64 , 100.0 )f3 = ns . FilterBandPassFIR( 500.0 , 64 , 100.0 , 200.0 )f4 = ns . FilterBandRejectFIR( 500.0 , 64 , 100.0 , 200.0 )
f1 . plot()f2 . plot()f3 . plot()f4 . plot()
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 6 4 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
48 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
53/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
H i g h P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 6 4 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
B a n d P a s s F I R F r e q u e n c y R e s p o n s e
e r = 6 4 , f l = 1 0 0 . 0 H z , f l = 2 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.2. FIR Filter Frequency Response 49
-
8/12/2019 nsound-0.9.0-userguide
54/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
B a n d R e j e c t F I R F r e q u e n c y R e s p o n s e
e r = 6 4 , f l = 1 0 0 . 0 H z , f l = 2 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.3 FIR Filter Frequency Response vs Filter Order
The plots below demonstrate the e ff ects of lter order.
import Nsound as ns
f1 = ns . FilterLowPassFIR( 500.0 , 16 , 100.0 )
f2 = ns . FilterLowPassFIR( 500.0 , 64 , 100.0 )f3 = ns . FilterLowPassFIR( 500.0 , 256 , 100.0 )f4 = ns . FilterLowPassFIR( 500.0 , 1024 , 100.0 )
f1 . plot()f2 . plot()f3 . plot()f4 . plot()
50 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
55/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 1 6 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 6 4 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.3. FIR Filter Frequency Response vs Filter Order 51
-
8/12/2019 nsound-0.9.0-userguide
56/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 2 5 6 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s F I R F r e q u e n c y R e s p o n s e
o r d e r = 1 0 2 4 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.4 IIR Filters
IIR lters are not stable for all orders and cut o ff frequencies, they have asymmetrical phase dis-tortion, but they are computationally inexpensive compared to FIR designs (because they performfar fewer multiplications).
Currently, Nsound designs IIR lters using Chebyshev type 1, ripples in the pass band. See DSPfor Scientists and Engineers, Chapter 20 , Table 20-4, 20-5. If the ripple percent parameter is set
52 Chapter 6. Nsound Filters
http://www.dspguide.com/CH20.PDFhttp://www.dspguide.com/CH20.PDF -
8/12/2019 nsound-0.9.0-userguide
57/77
Nsound Users Guide, Release 0.9.0
to 0.0, then the lter is maximally at and equilavent to a Butterworth lter. Consider using 0.005(0.5%) as the ripple percent, this acchives a sharper roll o ff with little ripple.
6.5 IIR Filter Frequency Response
Frequency responses for IIR lters:
import Nsound as ns
ripple = 0.005
f1 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , ripple)f2 = ns . FilterHighPassIIR( 500.0 , 4, 100.0 , ripple)f3 = ns . FilterBandPassIIR( 500.0 , 4, 100.0 , 200.0 , ripple)f4 = ns . FilterBandRejectIIR( 500.0 , 4, 100.0 , 200.0 , ripple)
f1 . plot()f2 . plot()f3 . plot()f4 . plot()
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.5. IIR Filter Frequency Response 53
-
8/12/2019 nsound-0.9.0-userguide
58/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
H i g h P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
B a n d P a s s I I R F r e q u e n c y R e s p o n s e
e r = 8 , f l = 1 0 0 . 0 H z , f h = 2 0 0 . 0 H z , s r = 5 0 0 . 0 H z
54 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
59/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
B a n d R e j e c t I I R F r e q u e n c y R e s p o n s e
e r = 3 , f l = 1 0 0 . 0 H z , f l = 2 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.6 IIR Filter Frequency Response vs Filter Order
The plots below demonstrate the e ff ects of lter order.
import Nsound as ns
ripple = 0.005
f1 = ns . FilterLowPassIIR( 500.0 , 2, 100.0 , ripple)f2 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , ripple)f3 = ns . FilterLowPassIIR( 500.0 , 8, 100.0 , ripple)f4 = ns . FilterLowPassIIR( 500.0 , 16 , 100.0 , ripple)
f1 . plot()f2 . plot()f3 . plot()f4 . plot()
6.6. IIR Filter Frequency Response vs Filter Order 55
-
8/12/2019 nsound-0.9.0-userguide
60/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 1 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
56 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
61/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 7 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 1 5 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.7 IIR Filter Frequency Response vs Ripple Percent
The plots below demonstrate the e ff ects of lter order.
import Nsound as ns
f1 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , 0.000 )f2 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , 0.005 )
6.7. IIR Filter Frequency Response vs Ripple Percent 57
-
8/12/2019 nsound-0.9.0-userguide
62/77
Nsound Users Guide, Release 0.9.0
f3 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , 0.010 )f4 = ns . FilterLowPassIIR( 500.0 , 4, 100.0 , 0.200 )
f1 . plot()f2 . plot()f3 . plot()f4 . plot()
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
58 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
63/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y ( H z )
6 0
5 0
4 0
3 0
2 0
1 0
0
L o w P a s s I I R F r e q u e n c y R e s p o n s e
o r d e r = 3 , f c = 1 0 0 . 0 H z , s r = 5 0 0 . 0 H z
6.7. IIR Filter Frequency Response vs Ripple Percent 59
-
8/12/2019 nsound-0.9.0-userguide
64/77
Nsound Users Guide, Release 0.9.0
60 Chapter 6. Nsound Filters
-
8/12/2019 nsound-0.9.0-userguide
65/77
CHAPTER
SEVEN
NSOUND FFT
Nsound currently implements its own fast Fourier transform (FFT) in C ++ . In the furture this willchange and use the FFTW library if available.
The FFT is provided by the FFTransform class. It takes an input signal Bu ff er and transforms itinto the frequency domain. The basic documentation:
FFTransform ( sample_rate )
sample_rate The number of samples per second. The sample rate is used for creating plotswith correct axes.
FFTransform. fft ( x, n_order )
x The input Bu ff er.
n_order The size of the FFT to perform.
Returns an FFTChunkVector, representing the input signal chopped up into frames, whereeach frame is n_order is size.
FFTransform. ifft ( ff t_chunk_vector )
ff t_chunk_vector The input FFTChunkVector returned by ff t().
Returns an Bu ff er, where each FFTChunk in the FFTChunkVector is transformed back intothe time-domain.
The example below creates a square wave with 5 harmonics.
import Nsound as ns
sample_rate = 500.0
square = ns . Square(sample_rate, 5)
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
66/77
Nsound Users Guide, Release 0.9.0
fft = ns . FFTransform(sample_rate)
vec = fft . fft(b, 256 )
b. plot( "Input signal, 4 Hz Square wave" )
vec[ 0] . plot( "Frequency Domain" )
b2 = fft . ifft(vec)b2 . plot( "Reconstructed" )
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
I n p u t s i g n a l , 4 H z S q u a r e w a v e
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y H z
0 0
5 0
0 0
5 0
0
5 0
F r e q u e n c y D o m a i n
62 Chapter 7. Nsound FFT
-
8/12/2019 nsound-0.9.0-userguide
67/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
R e c o n s t r u c t e d
Notice that there are 5 peaks, these correspond to the 5 harmonics in the square wave.
7.1 Using a Window
Setting a window on the FFT object can get rid of edge e ff ects. This can improve the results whenlooking at the frequency domain, but it will a ff ect the reconstructed signal.
import Nsound as ns
sample_rate = 500.0
square = ns . Square(sample_rate, 5)
b = ns . Buffer()b
-
8/12/2019 nsound-0.9.0-userguide
68/77
Nsound Users Guide, Release 0.9.0
vec2[ 0] . plot( "Frequency Domain, With Hanning Window" )
b1 . plot( "Reconstructed, No Window" )b2 . plot( "Reconstructed, With Hanning Window" )
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y H z
0 0
5 0
0 0
5 0
0
5 0
F r e q u e n c y D o m a i n , N o W i n d o w
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
F r e q u e n c y H z
0 0
5 0
0 0
5 0
0
5 0
F r e q u e n c y D o m a i n , W i t h H a n n i n g W i n d o w
64 Chapter 7. Nsound FFT
-
8/12/2019 nsound-0.9.0-userguide
69/77
Nsound Users Guide, Release 0.9.0
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
R e c o n s t r u c t e d , N o W i n d o w
0 5 0 1 0 0 1 5 0 2 0 0 2 5 0
. 5
. 0
. 5
. 0
. 5
. 0
. 5
R e c o n s t r u c t e d , W i t h H a n n i n g W i n d o w
As you can see, using a window can clean up the frequency domain plot, but it should not be usedfor reconstructing the signal.
7.1. Using a Window 65
-
8/12/2019 nsound-0.9.0-userguide
70/77
Nsound Users Guide, Release 0.9.0
66 Chapter 7. Nsound FFT
-
8/12/2019 nsound-0.9.0-userguide
71/77
CHAPTER
EIGHT
NSOUND STRETCHER
Nsound implements pitch and time shifting using the Stretcher class. The algorithm is based on thepaper An Overlap-Add Technique Based On Wavefrom Similarity (WSOLA) For High QualityTime-Scale Modication Of Speech by Werner Verhelst and Marc Roelands.
With the Stretcher class, you can change the time of the singal without modifying the frequencycontent. Or, you can also scale the frequency content without modifying the time.
Please visit the Nsound examples webpage to listen to a 10 seconds stereo recording that wasdynamically time and pitch shifted.
Some of the basic documentation:
Stretcher ( sample_rate )
Stretcher. pitchShift ( x, factor )
x The input Bu ff er or AudioStream.
factor A percent change factor.
Stretcher. timeShift ( x, factor )
x The input Bu ff er or AudioStream.
factor A percent change factor.
The example below creates a signal and shifts it in time, but preserves the frequency content. Theresults are put into the frequency domain and plotted.
import Nsound as ns
sample_rate = 1000.0
stretch = ns . Stretcher(sample_rate)stretch . showProgress( True )
saw = ns . Sawtooth(sample_rate, 4)
67
http://nsound.sourceforge.net/examples/index.htmlhttp://nsound.sourceforge.net/examples/index.html -
8/12/2019 nsound-0.9.0-userguide
72/77
Nsound Users Guide, Release 0.9.0
fft = ns . FFTransform(sample_rate)fft . setWindow(ns . HANNING)
a = ns . AudioStream(sample_rate, 1)a
-
8/12/2019 nsound-0.9.0-userguide
73/77
Nsound Users Guide, Release 0.9.0
0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0
F r e q u e n c y H z
0 0
5 0
0 0
5 0
0
5 0
O r i g i n a l F r e q u e n c y D o m a i n
0 . 0 0 . 1 0 . 2 0 . 3 0 . 4 0 . 5 0 . 6
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
5 0 % T i m e S h i f t
69
-
8/12/2019 nsound-0.9.0-userguide
74/77
Nsound Users Guide, Release 0.9.0
0 . 0 0 . 5 1 . 0 1 . 5
2 . 0
T i m e ( s e c )
. 0
. 5
. 0
. 5
. 0
2 0 0 % T i m e S h i f t
0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0
F r e q u e n c y H z
5 0
0 0
5 0
0
5 0
5 0 % P i t c h s h i f t
70 Chapter 8. Nsound Stretcher
-
8/12/2019 nsound-0.9.0-userguide
75/77
Nsound Users Guide, Release 0.9.0
0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0
F r e q u e n c y H z
5 0
0 0
5 0
0
5 0
2 0 0 % P i t c h S h i f t
71
-
8/12/2019 nsound-0.9.0-userguide
76/77
Nsound Users Guide, Release 0.9.0
72 Chapter 8. Nsound Stretcher
-
8/12/2019 nsound-0.9.0-userguide
77/77
INDEX
AAudioStream.ones() (built-in function), 16AudioStream.rand() (built-in function), 16AudioStream.writeWavele() (built-in func-
tion), 17
AudioStream.zeros() (built-in function), 16BBuff er.ones() (built-in function), 14Buff er.rand() (built-in function), 14Buff er.writeWavele() (built-in function), 17Buff er.zeros() (built-in function), 14
FFFTransform() (built-in function), 61FFTransform. ff t() (built-in function), 61
FFTransform.i ff t() (built-in function), 61FilterBandPassFIR() (built-in function), 47FilterBandRejectFIR() (built-in function), 47FilterHighPassFIR() (built-in function), 47FilterLowPassFIR() (built-in function), 47
GGenerator() (built-in function), 33Generator.drawDecay() (built-in function), 33Generator.drawFatGaussian() (built-in func-
tion) 33
NNsound.AudioPlayback() (built-in function), 25Nsound.Clarinet() (built-in function), 30Nsound.DrumBD01() (built-in function), 30Nsound.DrumKickBass() (built-in function), 30
Nsound.FluteSlide() (built-in function), 31Nsound.GuitarBass() (built-in function), 29Nsound.Hat() (built-in function), 30Nsound.Instrument.play() (built-in function), 29Nsound.OrganPipe() (built-in function), 30Nsound.use() (built-in function), 26
SSawtooth() (built-in function), 44Sawtooth.generator() (built-in function), 44Sine() (built-in function), 40Sine.generator() (built-in function), 40Square() (built-in function), 45Square.generator() (built-in function), 45Stretcher() (built-in function), 67Stretcher.pitchShift() (built-in function), 67Stretcher.timeShift() (built-in function), 67
WWavele.setDefaultSampleRate() (built-in func-
tion), 17Wavele setDefaultSampleSize() (built in func