Chord generator

i would like to develop the feature on each strum of a guitar would generate its respective corresponding chord… First problem is how to access the audacity software and develop it… i hope someone could guide me how to edit this software… i have already downloaded CVS & wxwidgets 2.8.9…

I’m guessing that you don’t have a lot of programming experience, in which case you are in the same situation as myself and will probably do best at looking into Nyquist programming.

“Nyquist” is a programming language that is built into Audacity and allows you to start writing plug-ins using nothing more than an installed copy of Audacity and a text editor (and the Nyquist manual).

You can find more about Nyquist here: http://audacityteam.org/wiki/index.php?title=Nyquist_Basics:_The_Audacity_Nyquist_Prompt

yeah im still a beginner equipped only with C/C++. Basic programming you say, that’s why if i ever got a chance in expanding my knowledge in creating or developing softwares. i hope i could catch with you guys :sunglasses:

@steve
so your saying, that i code my expected feature plug-in as nyquist file then embed it into a audacity? either you use unicode or stable type audacity , right? :wink:

i kinda have a question with audacity repository. its asking about a password when accessing this through CVS. hmmm

-d:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity checkout -r AUDACITY_1_2 audacity

The beauty of using Nyquist is that you can use it to write plug-ins and then just copy them to the Audacity plug-in folder. They do not have to be compiled into the Audacity code, which makes development much easier. This is how, for example, the high-pass and low-pass filters are done in Audacity 1.3

I do all my Nyquist development on Audacity 1.3 though they should also work in Audacity 1.2.x
I don’t tend to bother testing on 1.2.x as it will be obsolete soon (Audacity 1.4 is due out later this year and will be the new “stable” version). Audacity 1.4 will be based on Audacity 1.3.x

If you use Audacity you don’t need to worry about compiling Audacity from source, just use a regular release version and get developing your effects.

If you are more interested in getting stuck into the core Audacity code, look here: http://audacityteam.org/wiki/index.php?title=Developer_Guide

@ steve
can you help me to get this logic right…
here’s the situation

electric guitar is attached to my PC and into audacity software… every strum of guitar ,example, chord G it will simultaneously load to the audacity screen that the chord i strum is a G chord.

where can i compare my strummed chords?

Woah! That’s a lot more difficult than what I previously thought you were trying to achieve.

I thought that you were trying to make a kind of “harmonic generator” that would generate chords by adding related frequencies (play a note of “C” and have Audacity produce an “E” and an “G” above it to generate a chord). It seems that what you really want is real time analysis of polyphonic sounds to calculate what the fundamental tones are present. In this case, I don’t think that Audacity is going to help very much - it isn’t designed to do things in real time.

From my few scraps of knowledge about this sort of thing, I think you would need to be using fast Fourier transform (FFT) to analyse the frequencies that are present. That is something that is beyond the scope of Audacities implementation of Nyquist (I think that you would need to use the “yin” function which is not included in Audacities version of Nyquist).

Some open source projects that may be relevant:
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/music/web/music.software.html
http://www.clam.iua.upf.edu/
http://marsyas.sness.net/about/overview
http://www.csounds.com/

And a shareware product: http://www.audioto.com/index.htm

some musicians (talented you say) as they hear a piece of song they can pick out what chord used out of that song. A qualitative attributes of a person into quantitative by using a software. hehe too bad i set aside of my first dream of mine hehe for a something of achievable


based on your statement above, the idea you give is the same as mine only that it is not in real time basis.

would you please share your thought about “harmonic generator”?


a stepping stone to a next side :slight_smile:

P.S.
are you alone here in this forum, steve? where are your colleagues?
anybody home, home, home (echo)

The way I would approach it is using a Nyquist script to process an individual strum/note. In practice you would probably want different chords in different parts of the music/tune, rather than running parallel intervals throughout.

Considering just one note:

  1. Use the “snd-follow” function to copy the shape (dynamics) of the note.
  2. Stretch the note (same as the “change speed” effect in Audacity) by specific amounts to create the desired harmonic. (for example 50% increase in speed to generate a perfect 5th above).
  3. Apply the envelope to any generated notes that have been slowed down and trim the length so that they will not be longer than the original. (higher notes will be shorter than the original, but that will probably sound OK).
  4. “scale” the amplitude of each note to produce the desired relative volume for each note in the chord (probably a bit louder in the bass notes than the treble).
  5. Add the notes all together (using the “sim” function).

Regarding the interface:
Use a drop down selection box to offer choices of the chord that will be selected. Each “choice” will then set the “stretch” amount for each generated note.

Method of using:
You would look at the waveform and select the note based on its shape (look at the attack/decay of the note) then apply the effect with the selected (chosen) chord.

More sophistication:
You could select a key that the chord is required to fit, and enter the notes that are being played from a “score sheet” (a text file) that is read by the plug-in. Then have a suitable algorithm to calculate the necessary “stretch” ratios. This would require detecting the start and end of notes (probably from the slope of the envelope) but would still not require pitch detection as you are entering this manually through the “score”. (pitch detection is the hard part that would be extremely complicated to achieve using Audacity’s Nyquist language).

Special considerations about using Nyquist in Audacity:
The “stretching” used in the above idea is somewhat complicated by the way that Audacity handles “warp”, so even this is not a simple programming task.

Here’s some sample code to play with in the Nyquist Prompt (listed in “Unsorted” effects in Audacity 1.3.6)

(setq samplerate (snd-srate s))
(sim 
(scale 0.5 (force-srate samplerate (stretch-abs 1.0 (sound s))))
(scale 0.4 (force-srate samplerate (stretch-abs 0.75 (sound s))))
(scale 0.3 (force-srate samplerate (stretch-abs 0.5 (sound s)))))

@steve

do you have any source code available of any feature from lower version say Audacity 1.3.2 which is now available in latest version(audacity 1.3.6)

id really appreciate if you can help me with it to serve as my basis in programming. pls pls pls…

I’m not sure exactly what you are asking for Brian.

The source code for many (all?) releases of Audacity are available from here:

http://sourceforge.net/search/index.php?group_id=6235&words=file_name%3A(%2Baudacity)+OR+release_name%3A(%2Baudacity)+OR+release_notes%3A(%2Baudacity)+OR+changelog%3A(%2Baudacity)&type_of_search=files&pmode=0&limit=100

(copy and paste the link)


For information about Nyquist, including the manual and example code, follow the links on the main Audacity web site.
http://audacityteam.org/help/nyquist

@sir steve

is it possible to extract frequency as output in Audacity from an input source of Electric guitar (time basis = non real-time)?.. imagine, when the user tune his/her guitar electronically… so my basis would be in frequency

at least the scope at most to standard tuning… if ever possible, can you help me with it??

I presume that what you are wanting to do is to create an effect that tracks the fundamental input frequency.

I’m not a programmer, so for all that C+ stuff I can’t help you. I know a little about Nyquist scripts (much easier than real programming) http://en.wikipedia.org/wiki/Nyquist_(programming_language) . In the full version of Nyquist (free download) there is a function called yin for this kind of thing, but it is not included in the Audacity implementation of Nyquist, so to use it you would need to use the standalone version of Nyquist.

Working with Nyquist in Audacity, you may be able to test against specific frequencies by filtering the sound through a very narrow band-pass filter and then measuring the amplitude. With a series of filters, each set to one note of your chosen scale, the one with the highest input would probably be the note being played.

Here’s a snippet that I wrote for making a very narrow notch filter. Note that the higher the “width” value is, the narrower the band pass will be, but the longer it will take to process.

;; very narrow band pass filter
(setq frequency 440)   ; This sets the frequency to 440Hz (A)
(setq width 16)   ; Number of iterations - higher number for narrower bandpass
(setq amplify 2.0)    ; amplification factor to keep the level reasonable

;; start of function
(defun makenote (note freq q amp)
(dotimes (n q note)
(setq note (scale amp (highpass8 (lowpass8 note freq) freq)))))

;; call function
(makenote s frequency width amplify)

To avoid dithering noise, ensure that your audio is recorded in 32 bit. (all processing is done at 32 bit)

im sorry i didnt fully specify what i want…

fork tuning displays frequency or MIDI from a user input…if i set 440Hz then it generate its corresponding tone

heres the code (by david R sky)

;nyquist plug-in
;version 1
;type generate
;name "Tuning Fork..."
;action "Generating tone..."
;info "by David R. SkynReleased under terms of GNU Public Licensenmiddle C=MIDI note 60 A440=69"

;control dur "Tone duration" real "seconds" 5.0 0.0 300.0
;control cf "Constant volume or fade out" int "0=constant 1=fade" 0 0 1
;control mf "MIDI or frequency" int "0=MIDI 1=frequency" 0 0 1
;control midin "MIDI note" real "MIDI note" 69.0 16.0 127.0
;control f "frequency" real "Hz" 440.0 20.0 20000.0

; Tuning Fork by David R. Sky
; updated january 4, 2006
; Released under terms of the GNU Public License
; http://www.opensource.org/licenses/gpl-license.php

; set correct frequency
(setf midin (if (= mf 0) midin (hz-to-step f)))

; envelope function
(defun envelope (cf dur)
(if (= cf 0)
(pwl 0.002 1 (- dur 0.002) 1 dur)
(pwl 0.002 1 dur)))

; generate tone
(mult (envelope cf dur) (osc midin dur))

my study is exactly the reverse of tuning fork only that it picks/captures the analog input of an electric guitar…

I’m having trouble understanding your question.

You want a plug-in that will do the following?
Record a note from your guitar. Run the plug-in and if it is an “A” then it will output that it is an “A”. If it is another note, then it will output what note it is.

Is that what you are after?

You know that if you record a note, then select “Plot Spectrum” from the Analyze menu, it will display a frequency graph. The highest peak in the graph will occur at the fundamental frequency of the note that you are analysing. If the note is an “A”, then you will see a peak at 440 Hz.

Eureka… plot spectrum really defines my problem.

You want a plug-in that will do the following?
Record a note from your guitar. Run the plug-in and if it is an “A” then it will output that it is an “A”. If it is another note, then it will output what note it is.

a really big YES… :smiley:

is audacity plug in capable of this job:?: since it is the only part in audacity development i know that i can make modification.

That was the point of my previous post.

If you write a plug-in that passes the audio through a series of narrow band pass filters, then the relative signal level should correspond with the signal level shown for that frequency band in “Plot Spectrum”. The frequency band that has the highest signal level should correspond with the highest peak in the “Plot Spectrum” graph.


Here’s an example Nyquist script that can identify the notes A to G in the range 440 to 784 Hz that is based on the filter previously described. For it to work, the audio being tested must be a reasonably pure tone in the stated range:

;; start of function
(defun findnote (note freq q amp)
(dotimes (n q note)
(setq note (scale amp (highpass8 (lowpass8 note freq) freq)))))

(setq width 6)
(setq amplify 2.0)
(setq maxlength 30000)

(setq A (snd-max (findnote s 440.00 width amplify) maxlength))
(setq B (snd-max (findnote s 493.88 width amplify) maxlength))
(setq C (snd-max (findnote s 523.25 width amplify) maxlength))
(setq D (snd-max (findnote s 587.33 width amplify) maxlength))
(setq E (snd-max (findnote s 659.26 width amplify) maxlength))
(setq F (snd-max (findnote s 698.46 width amplify) maxlength))
(setq G (snd-max (findnote s 783.99 width amplify) maxlength))

(if (and (> A B)(> A C)(> A D)(> A E)(> A F)(> A G))(print "A")
(if (and (> B A)(> B C)(> B D)(> B E)(> B F)(> B G))(print "B")
(if (and (> C A)(> C B)(> C D)(> C E)(> C F)(> C G))(print "C")
(if (and (> D A)(> D B)(> D C)(> D E)(> D F)(> D G))(print "D")
(if (and (> E A)(> E B)(> E C)(> E D)(> E F)(> E G))(print "E")
(if (and (> F A)(> F B)(> F C)(> F D)(> F E)(> F G))(print "F")
(if (and (> G A)(> G B)(> G C)(> G D)(> G E)(> G F))(print "G")
(print "not found"))))))))

I doubt that this is the best way to do it, but perhaps it will get you started.
It would probably be better to use FFT, but the mathematics of that are beyond me. There’s some information about FFT here: http://etoile.berkeley.edu/~jrg/ngst/fft/fft.html

I would probably be better to use FFT, but the mathematics of that are beyond me

i have a FFT diagram based on VB code… manual user input only… if you have any use of it , tell me.

for now, i should try your code and study it… really big thx

how do i interpret each line?? correct me if im wrong… pls help me deduce this code

(defun findnote (note freq q amp)

above line is to declare findnote as a function call where it has a instance variable of note , freq, q, & amp


(dotimes (n q note)

dotimes is to iterate “q” in n times of a note,
n is the return value of how many sample rates are there, right?
therefore… 6 * sample rate of a note?

(setq note (scale amp (highpass8 (lowpass8 note freq) freq)))))

(symbol) “note” (expr) extract the value of amplitude multiplied by highpass2 * 4 in frequency multiplied by low pass2 * 4 in frequency

(setq width 6)

→ assign 6 to width

(setq amplify 2.0)

→ assign 2.0 to amplify

(setq maxlength 30000)

→ assign 30000 to maxlength

(setq A (snd-max (findnote s 440.00 width amplify) maxlength)))

symbol “A” ( snd-max (expression maxlength)
the expression is (findnote s 440.00 width amplify) then maxlength
findnote is has a instance variable of note = s which is 0.25 for 4/16 … what is 4/16 in music?? is it 1/4 comma meantone??
freq = 440.0
width = 6
amplify = 2 and then multiply freq, width, s and amplify… right?

The Nyquist manual is available here: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/manual/title.html

The index: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/manual/indx.html (useful for looking up functions)

Note that there are a few things in the manual that are slightly different from how Nyquist works in Audacity (because of the way that Audacity implements Nyquist), but the 2.37 version of Nyquist is the closest reference available.

The XLisp manual is also very useful: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-man/xlisp-man-index.htm (Nyquist is based on XLisp)

dotimes

(dotimes (n q note)

Iterate “q” times and return “note”. “n” is the “counter” (the symbol that is incremented on each loop).

(setq note (scale amp (highpass8 (lowpass8 note freq) freq)))))

Working from the innermost parentheses outward:
“note” is a sound (passed to the function)
“lowpass8” applies a lowpass filter to it at frequency “freq”
The result of that then has a highpass filter applied to it at frequency “freq”
the result of that is then amplified (multiplied / scaled) by “amp”
“note” takes the new value.
You could write it as:

(setq note 
   (scale amp 
      (highpass8 
         (lowpass8 note freq) 
      freq)
   )
)

The actual code has two more closing parentheses that belong to previous lines.

snd-max
The function “findnote” (probably not a great name) is simply a very narrow band filter.
“snd-max” looks at the sound returned from the filter and calculates the maximum absolute sample value (the maximum amplitude of the wave). I could have used “peak” instead of “snd-max” but I thought that "snd-max was a bit more descriptive.

Overall, the code passes the sound through extremely narrow band filters with centre frequencies set at different note values and assigns the result of each to a variable. It then compares the peak amplitude of each of these and tells you which has the highest amplitude.