FE 'tkGooies' Utilities

'AUDIOtools' group

tkPlayChords_withSox
'tkGooie' utility

(a FrontEnd for the
Sox 'play' command)

(FE = Freedom Environment)

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'AUDIOtools' Page >

This 'tkPlayChords_withSox' tkGooie Page

INTRODUCTION to
'tkPlayChords_withSox'

For about a year now (circa 2015), I have been planning to make a Tk GUI 'front end' for one or more commands of the SoX audio system that is is available on Linux.

On a vacation in January 2016, I noticed that I did not have the SoX audio system programs on the little Acer netbook that I take on vacations.

I downloaded the necessary binary package components from the snapshot.debian.org web site --- in particular, from the sox binary packages page.

On looking at the 'man page' for 'sox', I saw an example command for playing a G-major guitar chord



   play -n synth pl G2 pl B2 pl D3 pl G3 pl D4 pl G4 \
      delay 0 .05 .1 .15 .2 .25 remix - fade 0 4 .1 norm -1


This example uses the 'play' command of the Sox system.

I decided to start programming a Tk GUI based on that command.


THE GOALS

I noted that Sox 'play' had provisions for playing notes based on using the letters A through G with an integer indicating the octave.

Examples:
G2 represents G in a 2nd octave
and
D3 represents D in a 3rd octave.

Sharp and flat notes can be indicated by attaching a '#' or a 'b' character.

Examples:
Bb for B-flat
and
A# for A-sharp.

A main goal for the Tcl-Tk script was to provide buttons on the GUI to allow playing chords corresponding to 12 notes in an octave --- and to provide buttons by which to play several types of chords in a given key --- such as a major chord, a minor chord, a major-seventh chord, and an augmented-fifth chord (4 chord types).

After I developed the initial GUI --- with 48 buttons for the 12 x 4 = 48 chords --- I realized that the GUI should provide the ability to play a text 'chords-file' --- using a simple format for the file --- one line for each chord to be played --- with a chord-ID and a number indicating the time-length of the chord on each line of the file.

Ideally, I wanted to play chords that sound like they come from other instruments than just the guitar --- for example, instruments like a piano or harpsichord or pipe-organ or harp or chimes.

But I was not able to find sox commands for most of these other instruments.

And, as it turned out, it took a lot of coding and testing to just get the 'guitar' part of the GUI going.

So for the time being, I decided to provide 'grayed-out' radiobuttons on the GUI for some instruments in addition to 'guitar'.


THE GUI LAYOUT

Below is a 'text-sketch' that I used in planning the GUI for this 'play-chords' utility.



CONVENTIONS for the GUI 'text-sketch' below:

   * SQUARE-BRACKETS indicate a comment not to be included on the GUI.
   * BRACES indicate a Tk 'button' widget.
   * UNDERSCORES indicate a Tk 'entry' widget.
   * A COLON indicates that the text before the colon is on a 'label' widget.
   * CAPITAL-O indicates a Tk 'radiobutton' widget.
   * CAPITAL-X indicates a Tk 'checkbutton' widget.

  FRAMEnames
  VVVVVVVVVV
              ------------------------------------------------------------------------------------------
              tkPlayChords --- using the Sox system 'play' command
              [window title]
              ------------------------------------------------------------------------------------------

 .fRbuttons   {Exit} {Help} {PlayChordsFile} Chords filename: __________________  {GetFilename}

 .fRinstrmnt  Instrument:  O Guitar   O Piano  O Harpsichord  O Harp   O Chimes
    
              [An '.fRbottom' FRAME, below the '.fRinstrmnt' frame, contains at least
               12 frames left to right --- each of which will contain a stack of buttons.]

              ['.fR_C'  ['.fR_C#' .............................................. ['.fR_B'
               frame ]    frame]                                                  frame ]


              [These 12 frames contain the following stacks of several buttons and a label.]

              {aug5}    {aug5} ............................................... {aug5}
              {maj7}    {maj7} ............................................... {maj7}
              {min}     {min}  ............................................... {min}
              {maj}     {maj}  ............................................... {maj}
 [labels->]     C       C#/Db  ...............................................   B


GUI Components

From the GUI 'sketch' above, it is seen that the GUI consists of about

  • 52 button widgets (or more)
  • 13 label widgets
  • 1 entry widget
  • 3 radiobutton widgets (or more)
  • 0 checkbutton widgets
  • 0 scale widgets
  • 0 listbox widgets
  • 0 canvas widgets
  • 0 text widgets

I later added a 'Chord secs' scale widget to the '.fRinstrmnt' frame.


I should point out here that I was not especially interested in coming up with a 'beautiful utility'.

I just wanted a utility that would make playing chords, with Sox 'play', as simple as clicking on buttons.

I am certainly interested in making pretty GUI's --- as my pages on

and

have indicated.

But at this time, I am satisfied to implement the 'functionality', and let the 'beauty' go for a later date (when I have more beauty tools/code at hand).


SCREENSHOT OF THE GUI

On the basis of the GUI-layout sketch above, I ended up with the GUI seen in the following image.


Perhaps a better name for the
'GetFilename' button would be 'Browse...'
--- to be more like other GUI's with
a file-navigate-and-select feature.

When the GUI first comes up, the user can simply click across a row of buttons to hear the chords corresponding to an octave scale.

Click across the bottom row of buttons to hear 'major' chords.

The user can use the 'Chord secs' scale widget to adjust the length of time that each chord will play --- on the order of 1 to 5 seconds.


A 'chords-file'

I have provided a sample chords file with the Tk script.

The full-filename of the example 'chords-file' is provided in the filename entry field when the GUI first starts up.

Thus, the user can simply click on the 'PlayChordsFile' button to hear a sample of playing a 'chords-file'.

The simple format of the example chords file can be seen via a link to the file provided below --- just below the link to the code for the Tk script.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'play-chords' utility.

I follow my usual 'canonical' structure for Tk code for this Tk script:



  0) Set general window and widget parms (win-name, win-position,
     win-color-scheme, fonts-for-widgets, widget-geometry-parms,
     text-array-for-labels-etc, win-size-control).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define and pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in other scripts (code re-use).

I call your attention to step-zero.

One thing that I started doing in 2013 is use of a text-array for text in labels, buttons, and other widgets in the GUI.

This can make it easier for people to internationalize my scripts.

I will be using a text-array like this in most of my scripts in the future.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main 'pack' parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think that I have used a pretty nice choice of the 'pack' parameters.

The label and button and scale widgets stay fixed in size and relative-location if the window is re-sized.

    I allow the window to be resized although there is probably not a need to resize it --- unless you want to squeeze it down temporarily.

    If you want to fix the window size, you can de-comment the line

    wm resizable . 0 0

You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want.


Additional experimentation with the GUI:

You might want to change the fonts used for the various GUI widgets.

For example, you could change '-weight' from 'normal' to 'bold' --- or change '-slant' from 'roman' to 'italic' --- or change the font sizes.

Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding.

And I have included the '-relief' parameter on the definitions of frames and widgets.

Feel free to experiment with those 'appearance' parameters as well.

If you find the gray palette of the GUI is not to your liking, you can change the value of the RGB parameter supplied to the 'tk_setPalette' command near the top of the code.


Some features in the code

There are plenty of comments in the code, to describe what most of the code-sections are doing.

You can look at the top of the PROCS section of the code to see a list of the procs used in this script, along with brief descriptions of how the procs are called and what they do.

Below is a quick overview of the procs.



  - 'play_chord'         - called by the following 'play_<chordID>' procs.

  - 'set_guitar_parms'   - called in the 'Additional GUI Initialization'
                           section at the bottom of this script --- to set
                           parms used by the following 'play_<chordID>' procs.

  - 'play_Cmaj'          - called by a button
  - 'play_Cmin'          - called by a button
  - 'play_Cmaj7'         - called by a button
  - 'play_Caug5'         - called by a button

     and 11 more groups of procs like these four, corresponding to the notes
     C#, D, D#, E, F, F#, G, G#, A, A#, B.

  - 'play_R'                  - called by the 'play_chords_file' proc
                                (to 'play' a rest)

  - 'get_filename'            - called by the 'GetFilename' button
  - 'play_chords_file'        - called by the 'PlayChordsFile' button

  - 'popup_msgVarWithScroll'  - called by the 'Help' button


See the comments in the 'play_chord' and 'play_chords_file' procs for some details on how the chord playing is implemented.


A fervent hope

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to listen to songs their mother would never sing to them.


CODE for the Sox 'play-chords' Front End GUI

Here is a link to the code for the Tk script :

'tkPlayChords_withSox.tk'

Also, here is a link to the example 'chords-file'.

'chords_example.txt'

With your web browser, you can 'right-click' on each link --- and in the menu that pops up, select an item like 'Save Link Target As ...'   ---   to save the file to your local computer.

Then you can rename the Tk script file to remove the '.txt' suffix.

Make sure that you have execute permission set on the file --- in order to execute the script.

Simply put the 'chords_example.txt' file in the same directory with the Tk script.


A SOURCE OF 'sox':

I did my testing of this GUI front-end with version 14.3.0 (circa 2009 July) of 'sox'.

If someone is using a Debian-based Linux system such as Linux Mint or Ubuntu --- or Debian itself --- various versions of a binary package of the 'sox' program can be found at the snapshot.debian.org web site --- in particular, on the sox binary packages page.

For Intel or AMD 32-bit or 64-bit machines, you can download a '.deb' file such as 'sox_14.3.0-1_i386.deb' or 'sox_14.3.0-1_ia64.deb' --- or a much more recent version.

Once you have downloaded the '.deb' file into a download directory on your computer, to do the install, you can right-click and choose to run Gdebi --- if you are using a GUI file manager on Linux Mint or Ubuntu or Debian.

The 'Gdebi' utility should advise you of any additional packages that you may need to download --- such as 'libsox' packages.


SOME POSSIBLE ENHANCEMENTS

There may be some improvements (and fixes) to be made to some of the chords played by the 48 buttons.

Let your ear be the judge.

More Chords

The array of buttons could be expanded horizontally (to extend to other octaves) and vertically to add more chord types (such as a row of 'min7' buttons to play minor-seventh chords).

More Instruments

Eventually (when I can determine appropriate parameters for the Sox 'play' command), I may activate the instrument-radiobuttons on the GUI --- to allow for playing the chords such that they sound like they are coming from a piano or harpsichord or harp or pipe-organ or chimes or another instrument.

Some Unsettled (and unsettling) Issues

When clicking on the chord-buttons, there may be times when the chord does not immediately play.

It would be nice to be able to guarantee that a chord plays precisely when it is requested.

Some similar timing issues may be encountered when playing chords in a chord-file.

The (open-ended) Bottom Line

This little programming project was meant to probe the 'synthesis' capabilities of the 'sox' system --- and make it much easier to probe those capabilities.

With this 'initial, experimental' Tk GUI front-end to the Sox 'play' command, I have just scratched the surface of the possibilities.

In order to expand the capabilities of this utility, I may first develop a couple of other Tk GUI's to facilitate experimenting with Sox 'play' parameters for generating

  • single tones of various timbres
    (say, layers of harmonics)

  • chords that sound like they come from earthly and unearthly instruments

I have so many Tk GUI's on my 'to-do' list --- in many other categories --- PLOTtools, IMAGEtools, VIDEOtools, MATHed, etc. --- that it may be many months before I get back to more Sox utilities --- and this utility.


IN CONCLUSION

As I have said on several other code-donation pages on this site and on the Tclers' wiki at wiki.tcl.tk ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.

Bottom of this page for
tkPlayChords - a Sox 'play' FrontEnd
--- a utility in the FE 'tkGooies' system,
in the 'AUDIOtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

This FE web page was created 2016 Feb 04

Page was changed 2019 Feb 27.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 25.
(Specified image widths in percents to size the images according to width of the browser window.)


NOTE:
This code has not been posted on a page at the Tcler's Wiki ---
wiki.tcl-lang.org --- formerly wiki.tcl.tk. If I donate the code on a page there, I intend to put a link here.