Output text to file

Nyquist can output to a file by opening a file stream, then “printing” to the file.

Typically this would be done by:

As an example on Windows, to create a text file called “test.txt” in the root directory (C:) containing the text “Hello World”

(setdir "C:/")
(setq file (open "test.txt"  :direction :output))
(format file "Hello World")
(close file)

One important thing to notice is that the directory must be defined using forward slashes and not backslashes. This is because Nyquist uses backslash as an escape character.

Another thing to notice is that this does not work on Linux (or Mac ?) because they do not use the same drive letter notation.
(it probably does not work on Windows if the user has a limited account - can anyone confirm?)

On Linux, we could use “~/” to specify the users “Home” folder, so the Linux equivalent would be:

(setdir "~/")
(setq file (open "test.txt"  :direction :output))
(format file "Hello World")
(close file)

If the default “working directory” was reliably in a usable location, then we could just use that and not worry about cross-platform differences.
In Audacity 1.3.12 and 1.3.13 (alpha) on Ubuntu, the default working directory is the users home folder. This is good.

To display the working directory - enter the following code in the Nyquist prompt:

(setdir ".")

What is the default working directory for Mac and Windows?

The default working directory on Mac is the Audacity application folder. In my case /Applications/Audacity 1.3.13/

(setdir “~/”) does not work, i.e. does not change the directory written to, despite OS X’s Linux underpinnings :frowning:

If I change it to (setdir “/Users/Bill”) it then writes to my home folder.

The code to write the Hello World file works, but the file “test.txt” is written to the working directory.

– Bill

Just noticed that in my browser that looks like “hyphen, forward slash”, but in fact it is “tilda, forward slash”

Just in case others have similar display problems, a “tilda” is the “squiggle” that looks a bit like an “S” on its side Tilde - Wikipedia

Thanks for the feedback Bill. I presume that on Mac OS X the /Applications/ directory is writeable for non-admin users?

From http://audacity.238276.n2.nabble.com/Setting-Nyquist-working-directory-tp4134136p4144136.html

On MS Windows you cannot reliably re-construct the
user’s HOME directory only by the username, because on Windows
the path of the HOME directory is localized:

In an english Windows the user’s home directory is something like:
C:documents and settings[username]my files

In a german Windows the same home directory is something like:
C:Dokumente und Einstellungen[username]Meine Dateien

It appears that Nyquist in Audacity has been updated and now has a function to return the “Home” directory.
The function is (getenv) but unfortunately it does not work on Linux.

Could someone try the following on Windows / Mac and say if they get the home directory (on Linux it just returns “NIL”)

(print (getenv))

You may need to press the Debug button to see the output.

On Mac it returns NIL.

Yes, I knew that was a tilde. Anyway, I copied and pasted the code.

– Bill

I think to get the path to the user’s home directory you need to specify the OS’s variable name, where the home directory path is stored:

(print (getenv "HOME"))

Or at least this is how it works in all other Lisps. The “getenv” functions means something like “get the value of the specified system environment variable” and should [theoretically] also work with all other environment variables, not only “HOME”.

  • edgar

When I copy and paste that code into the Nyquist prompt I get:

error: too many arguments
Function: #<Closure-GETENV: #5a39214>
Arguments:
“HOME”
1>

– Bill

Confirmed on Debian_5 (Lenny) with Audacity 1.3.12-alpha-Oct 20 2010 (CVS HEAD from today), exactly the same error.

Also note that #<Closure-GETENV…> is part of the XLISP dynamic memory allocation functions and has nothing to do with the POSIX “getenv” function for accessing environment variables. This is obviously just another quirk with Nyquist in Audacity.

I do not think that the CMU-Nyquist “getenv” function has been added to Audacity like Steve had written above.

Audacity 1.3.12-alpha-Oct 20 2010 (CVS HEAD from today) on Debian_5 (Lenny).

Confirmed, the Nyquist default working directory is my home directory.

Confirmed, Nyquist (setdir “~/”) does not change the Nyquist working directory to my HOME directory. If the first character is a tilde, then the Nyquist working directory is not changed at all.

According to the Nyquist/XLISP function table in “lib-src/libnyquist/nyquist/xlisp/xlftab.c” there is no “getenv” function for accessing environment variables implemented in Audacity. I think Nyquist in Audacity confuses “getenv” with “closure-getenv”, what is a different function.

Correction: If I start Audacity from a shell window, then the Nyquist working directory is not my HOME directory, the Nyquist working directory then is the current working directory of the shell at the time when Audacity was started. I also get SETDIR error messages in the shell window after Nyquist in Audacity had been started for the first time:

; loading "/usr/local/share/audacity/nyquist/init.lsp"
SETDIR: file or directory not found
Set *default-sf-dir* to "/home/edgar/Downloads/audacity/audacity-2010-10-20/lib-src/libnyquist" in fileio.lsp
AutoNorm feature is on.
Default sound file is edgar-temp.wav.
system.lsp : *RUNTIME-PATH* = /usr/local/share/audacity/nyquist/  

Nyquist -- A Language for Sound Synthesis and Composition
    Copyright (c) 1991,1992,1995,2007-2009 by Roger B. Dannenberg
    Version 3.03

SETDIR: file or directory not found

I have no idea what the SETDIR errors may be.

On Linux (Unbuntu 10.10) with Audacity 1.3.13
the following returns the home directory:

(print (get-env 'HOME))

For Windows it is the directory where the Audacity application lives; on my machine it is
C:Program FilesAudacityaudacity-win-unicode-1.3.13-alpha

I’m afraid it doesn’t work for me on Windows. It throws an error:

error: unbound function - GET-ENV
if continued: try evaluating symbol again
1>

POL

With Audacity 1.3.12-alpha-Oct 20 2010 (CVS HEAD from yesterday) on Debian_5 (Lenny), I get exactly the same error:

error: unbound function - GET-ENV
if continued: try evaluating symbol again
1>

In the Audacity-Nyquist C/C++ sources there still seems no way to determine the user’s HOME directory with build-in Nyquist/XLISP functions (but read this statement with the risk that I might have overlooked something).

Question: Is “Audacity 1.3.13” a typo or do there exist some “inofficial” builds? The current CVS HEAD under “Help > About Audacity” displays “Audacity 1.3.12-alpha”. Or is this a bug in the Audacity code and Audacity help window displays a wrong version number? The “official” Audacity versions from the Audacity Homepage are labeled “Audacity 1.3.12-beta”, so the “official” download versions are newer than CVS HEAD? What’s that for a quirk?

Can anybody confirm a wrong “Help > About Audacity” version number in Audacity CVS HEAD?

In case anybody wants to know what “getenv” does with Nyquist in Audacity:

(let ((a 1) (b 2) (c 3))
  (print (getenv)))

=> ((((C . 3) (B . 2) (A . 1))))

“getenv” calls “closure-getenv”, which returns the current lexical environment [i.e. all local “let” variables and their values] as an association list. This list is used e.g. in the XLISP object system to store a copy of the current lexical environment inside an object at the object’s creation time. But “closure-getenv” has nothing to do with accessing environment variables of the operation system.

No, not a typo. It clearly says Audacity ® 1.3.13-alpha-Oct 17 2010 (Unicode) in both my “Release build” and “Debug build”.

The source code was downloaded with:

svn checkout  http://audacity.googlecode.com/svn/audacity-src/trunk audacity



Thanks very much - that clears up one issue,
but where is this “GET-ENV” function that was committed to the Nyquist source last December?

I have revived the original topic on the Nyquist mailing list, so hopefully Roger can shed some light on this.
http://audacity.238276.n2.nabble.com/Setting-Nyquist-working-directory-td4134136.html#a4134136
@edgar-rtf I believe that you wrote the original code for getting the HOME-PATH didn’t you?

Maybe a mystery’s solution: I have checked out via cvs from SourceForge, so maybe the SF repo still contains an old Audacity 1.3.12-alpha version? I will now checkout from Google and try again.

Question: Is the SF repo officially obsolete?

Answer: yes, but Roger modified (improved) it, but unfortunately I can’t remember what was exactly changed. Roger usually only changes the CMU-Nyquist code, so this doesn’t mean that the GETENV code was ever added to Nyquist in Audacity at all.

P.S.: one hour later - Sorry, but the Discussion must be postponed because I’m unable to compile the Audacity code from Google, see
http://forum.audacityteam.org/viewtopic.php?f=24&t=42443 - no automake_1.10

As far as I’m aware CVS has not been updated for about 8 months.

I’m not a programmer, so I’m struggling to follow the code, but as far as I can tell the update that Roger committed is basically the same as what you wrote, but tidied up a bit. The main difference being that a function that you put into nyx.c has been put into xlsys.c

As far as I can tell this has never been committed in Audacity, but as I say, I’m really struggling when it comes to the C+ code, SVN and all that stuff :wink:

What I can tell from looking at the Google Audacity C/C++ code (but I’m a hardware electrician and not a programmer either):

In “lib-src/libnyquist/nyquist/xlisp/xlftab.c” (that’s the file where the build-in function names of the XLISP obarray are declared), there is a XLISP function named “GET-ENV” which takes one argument, calling a C-function named “xget_env”.

The “xget_env” C-function can be found in the file “lib-src/libnyquist/nyquist/xlisp/xlsys.c”, it converts the argument to a character-vector (i.e. a C-string) and tries to look-up the value of an system environment variable with the same name as the string. If a system environment variable is found, then the value of the variable is returned as a string. If no variable ist found, then NIL is returned.

This is how it should theoretically work in the Google SVN version. I still can’t try it because I can’t compile the code, but if the SourceForge CVS repo hasn’t updated for the last eight months, then this perfectly explains the version number mess. Hopefully I will find a way how to compile the Google code later on.

I’ve just seen a message from Roger Dannenberg on the Nyquist mailing list.

Apparently (GET-ENV) is now in the latest Audacity source code, but was not in Audacity 1.3.12
http://audacity.238276.n2.nabble.com/Setting-Nyquist-working-directory-tp4134136p5658828.html

so as I understand it, when Audacity 1.3.13 beta is released it should make life a whole lot easier for outputting text (or XML) files to the HOME directory.
It appears to be working on my computer, so hopefully people can report on whether it works in Windows and Mac as and when they get the new code.

On my G5 PPC Mac running 1.3.13-alpha-Oct 19 2010, running this line from the Nyquist prompt:

(print (get-env "HOME"))

outputs “/Users/Bill”

which is correct. :smiley:

What else can “get-env” return? Can it return the platform or OS? I’m thinking, e.g. on Mac, it would be nice to be able to get to “~/Library/Application Support/audacity”. But for those of us using the “Portable Settings” folder it would be nice to get the directory that Audacity is installed in.

– Bill

Now with Audacity_1.3.13-alpha from Google (thanks to Steve, the SourceForge CVS repository is really obsolete now).

Reading environment variables:

(get-env 'home)   => "/home/edgar"
(get-env "HOME")  => "/home/edgar"

Note that the first version is unreliable, because it only works here “by accident”. With symbol names, Lisp internally converts all characters to uppercase, and in this case with the HOME variable all letters are uppercase, too. But on systems with case-sensitive environment variables this trick won’t work, so it’s always better to specify the environment variable name as a string.

Reading and setting the current working directory:

(setdir ".")     => "/home/edgar"  ; reading the current working directory
(setdir "/tmp")  => "/tmp"         ; changing the working directory
(setdir "~/")    => "/tmp"         ; tilde doesn't work here (on Debian)

Changing the current working directory to the user’s HOME directory:

(setdir ".")               => "/tmp"         ; reading the current working directory
(setdir (get-env "HOME"))  => "/home/edgar"  ; changing the working directory
(setdir ".")               => "/home/edgar"  ; verifying the change

Audacity_1.3.13-alpha (from Google) on Debian_5 (Lenny):

If I start Audacity by clicking the GUI (Gnome 2.22.3), then the default Audacity Nyquist working directory is my HOME directory. If I start Audacity from a shell window, then the default Audacity Nyquist working directory is the current working directory of the shell, at the time when Audacity was started.

The value of every system environment variable of your operation system. If you type in the Mac terminal window a command like “env” [typically for Unix, but not sure if this works with Mac OS X exactly the same] then you should get a list of all currently visible environment variables and their values. The Nyquist “get-env” function should be capable to read them all.

On Debian I can read for example:

(get-env "TERM")     => xterm        ; name of my terminal
(get-env "SHELL")    => /bin/bash    ; name of my shell program
(get-env "USERNAME") => edgar        ; my user name
(get-env "LANG")     => de_DE.UTF-8  ; the current locale (german with UTF-8)

But please be aware that most of these variables (exept very basic ones like shown above) are highly system-dependent, and I don’t know if it is possible to identify the underlying operation system via environment variables in a reliable way.

Look out for a Mac environment variable where this value is stored, I would be willing to help with “variable search” on Linux and Windows.

Maybe we’ll be able to find a reasonable way how to manage directories?