Strange/Advanced batch processing help [2.0.5 .exe]

Hello, I got an insane impulse that I want to distort a lot of images at the same time/in a row using audacity, 7081 to be exact. I looked into the chain functionality and it lacks a few things that I need to get my stuff working. With this many pictures, it would take a few hours (118 hours assuming I can do one image per minute) to get it done manually, thus I’m looking for options.
What I need to do:
Import Raw Data Parameters: A-Law, Little endian, Mono, 0 byte offset, 100% Amount, 44100Hz Sample Rate

Some action that will let me select from a specific time in the track to the end, or stop selecting at a specific time. (The reason for this is that I need to keep the header intact when doing this)

Export Other uncompressed files Parameters: Raw (header-less), A-Law

Is there any way to make this work, can I write some kind of script that Audacity will accept or what are my options? My coding knowledge is non-existent but with some input and hefty googling I might be able to pull it off.

Audacity doesn’t export WAV in Chains other than 16-bit PCM.

If you must edit the images as audio, try SoX ( For help with SoX, .


Okay, disregarding the exporting because I might be able to solve that in some other way, are the other features possible to achieve via Chains somehow?

Have you tried importing images into Audacity other than with Import Raw? It doesn’t work. Nor is it supposed to.

Chains doesn’t work with Import Raw, and Import Raw can only import one file at a time, so you can’t use Audacity for your purpose in any automated way.


You can of course use the nyquist prompt for the import and export things (and actually everything inbetween…)
The main functions are ‘s-read’ and ‘s-save’ (or ‘s-overwrite’).
Here’s the exemplary ‘s-read’ description:

LISP-syntax for this Function (316/358):
Category: Sound File Input and Output, as found in :  Fileio.Lsp

Reads a sound from a file. If a header is detected, the header is used to determine the format of the file, and header information overrides format information provided by keywords (except for :time-offset and :dur). 
(s-read >mysound.snd< :srate 44100)
 specifies a sample rate of 44100 hz, but if the file has a header specifying 22050 hz, the resulting sample rate will be 22050. The parameters are: 
:time-offset - the amount of time (in seconds) to skip from the beginning of the file. The default is 0.0. 
:srate - the sample rate of the samples in the file. Default is *default-sf-srate* , which is normally 44100. 
:dur - the maximum duration in seconds to read. Default is 10000. 
:nchans - the number of channels to read. It is assumed that samples from each channel are interleaved. Default is 1. 
:format - the header format. See s-save for details. Default is *default-sf-format*, although this parameter is currently ignored. 
:mode - the sample representation, e.g. PCM or float. See s-save for details. Default is *default-sf-format*. 
:bits - the number of bits per sample. See s-save for details. Default is *default-sf-bits*. 
:swap - (T or NIL) swap byte order of each sample. Default is NIL. 
If there is an error, for example if :time-offset is greater than the length of the file, then NIL is returned rather than a sound. Information about the sound is also returned by s-read through *rslt*. The list assigned to *rslt* is of the form: (format channels mode bits samplerate duration flags byte-offset), which are defined as follows: 
Format - the header format. See s-save for details. 
channels - the number of channels. 
mode - the sample representation, e.g. PCM or float. See s-save for details. 
bits - the number of bits per sample. 
samplerate - the sample rate, expressed as a FLONUM. 
duration - the duration of the sound, in seconds. 
flags - The values for format, channels, mode, bits, samplerate, and duration are initially just the values passed in as parameters or default values to s-read. If a value is actually read from the sound file header, a flag is set. The flags are: snd-head-format, snd-head-channels, snd-head-mode, snd-head-bits, snd-head-srate, and snd-head-dur. For example, 
(let ((flags (caddr (cddddr  *rslt*))))
  (not (zerop (logand flags snd-head-srate))))

tells whether the sample rate was specified in the file. See also sf-info below. 
byte-offset - the byte offset into the file of the first sample to be read (this is used by the s-overwrite and s-add-to functions).

‘s-save’ has as first parameter a sound, followed by the number of samples to be written (we use ny:all for a infinite number, i.e. a giga samples)
The rest is similar
As you might have realized, the filename has to be explicit such as: “C:\myclips\clip001.wav”
However, you can put all the filenames of a specific directory into a list and work them thru one by one.
This prints the c: directory to the debug-screen (after copying the code into the nyquist prompt and pressing debug):

(print (listdir "c:"))

In pseudo code the reading and writing would be something like this:

(psetq indir "c:\myclips\"
      outdir "c:\myclipscopied\")
(dolist (file (listdir indir))
          (s-read (strcat indir file) <import-options>); this statement is the read sound
          ny:all (length in samples)
          (strcat outdir file) <export-options>))

(It becomes messy if you want to manually edit those files, i.e. return them to Audacity as individual tracks.)
The approach over the nyquist prompt (or a Nyquist plug-in) should be straightforward.

Note that nyquist can only work with lossless files such as *.wav or *.aiff.

My understanding though is the intention is to import images (presumably like PNG or JPG). Can Nyquist do that?


It can read anything that has bytes in it.
However, it does not perform any decoding (e.g. jpg)
Thus, you could import any file, skip the header and modify it artistically.
You could for example import a bitmap and save it as a ASCII picture (like in a sms).
It comes down to a simple filter:
input → transfer function → output
where the transfer function can be as simply as swapping the byte order or as complicated as lossy de-/encoding.

Thanks, Robert. As far as i can tell that doesn’t produce an output folder (I did use double slashes).

And even if the automation works, it won’t produce A-Law files.


There are applications online that can synthesize audio from images. It may produce a more interesting sound.


Well, it is pseudo code and written adhoc.
The output folder must exist (otherwise, we have to add a function to create it if non-existent)
A-Law headers are not supported but U-Law.

If I understand correctly, there’s actually no sound manipulation going on, so no A-Law quantization is required and the bytes can be treated just the way they are.
Even quantization is not much of an obstacle.
I actually don’t understand why A-law is used in the first place.
When the input is an image, why the A-Law header?
And why does the output have no header but the A-Law quantization?
An in-depth explanation of the whole procedure would be helpful.

Oh, cool, that means that using nyquist it might be possible?

I’ll try to explain my procedure as best as possible.
What I do is importing bitmap pictures using A-Law and Little-Endianess (I actually don’t know why these are used, the knowledge came from tutorials and trial and error as to what works with my workflow), with headers and all data intact, then I use random effects (like wahwah or reverb) on the data that isn’t the header as to corrupt the image in ways that are not intended by any program. It is important that effects that do not alter the length of the clip is used, as this will be different from the data in the header and thus rend the picture broken and being unable to be opened by anything. However if I only touch the image data, and not the header, I can safely export the project without a header (therefore headerless) and A-Law (because of consistency, I assume that the file would become unreadable if I change it to any other parameter) and open it up in a program that reads pictures because the original header is intact and thus it regards all the corrputed/changed data as normal.

Simply put: Import image > use audio effects on data that is not the header > Export with header intact > Read in a picture program > Results

Ok, you’re actually overwriting the data chunk with the processed audio from Audacity.
This means that the export isn’t headerless but has the original one instead.
Again, the image is a commonplace bitmap file (*.bmp)?
Could you attach a sample file?
The offset seems in general to be 54 Bytes for the data to start.
The usage of A-Law still seems querky and makes no sense to me.

As I’ve written above, the Nyquist way to do it is rather complicated due to the fact that Nyquist has no access to Audacity effects from within the code.

The plug-in won’t certainly not work within a chain (i.e. in file mode)
You will have to create as many empty tracks as there are files to be modified.
The first thing to do is trying reading one of your bitmaps per Nyquist Prompt, hopefully with the s-read command (fastest variant).
Since the header is not known, no header is assumed and we can give a proper offset:

offset in seconds = (/ (float N) sr (/ bits 8) channels)

N is the number of bytes to skip, sr the sample rate, the rest should be clear.

Yes, the image is a .bmp, here is a sample. All the other files share header size, total file size and dimensions with this picture. The white borders are added to give a greater distance between the header and the data I’m interested in.
The A-Law should not be a necessity if U-Law can be used (as you said was supported), it’s just a product of trial and error.

I created an empty track and tried to use Nyquist Prompt (from the Effects dropdown) but I got the error message “Disallowed. You must first select some audio for this to use.” So I couldn’t even try using it to read the bitmap files. Do I need to do anything more than create the track for this to work, or am I out of luck?

Try Generating one sample of tone. Nyquist Prompt requires some content in the track or it won’t open.


Last question first:
You have just to expand the selection, i.e. either changing the length of the selection or the end point, whatever is visible.
Generating a dummy sound (as Gale has mentioned) would of course work too.
Rreplacing -Law by U-Law does not work because we do not have the appropriate header.
Howeverr, tat’s not as bad as it sounds, on the contrary, we are more flexible.
We can in fact load the whole file into memory as 8-bit little endian 44100 kHz (or even as 1 Hz, which would allow direct byte access, scaling afterwards shouldn’t be a problem).
Loading the whole file would mean that the header(s) are included and we can read individual bytes, such as the data off-set, width and height and so on.
As my media-info tool tells me, we do have a 24 bit RGB image.
In the data block, the pixels are encoded with 3 bytes for BGR. At the end of the row, 0-value bytes are inserted to make the row divisible by 4 bytes.
Your sample file has the dimensions 884814 bytes - (673 x 438 x 3) = 492 - 438 x 1 zero-byte = 54 (offset for the header).
This proves that my initial 54 byte offset seems to work for your case.
I’m going to try reading the bitmap file now.
(The normal s-read doesn’t seem to work in Audacity, so I have to open the file as stream and read each byte sequentially)

Here’s the code that prints the important data from the header of your bitmap file:

(setf bmp-header '(
      ("nbfType " 0 1) ("" 0 1) 
      ("nbfSize " 1 -4)
      ("nbfReserved " 1 -4)
      ("nbfOffBits " 1 -4)
      ("nbiSize " 1 -4)
      ("nbiWidth " 1 -4)
      ("nbiHeight " 1 -4)
      ("nbiPlanes " 1 -2)
      ("nbitCount " 1 -2)
      ("nCompression " 1 -4)
      ("nbiSizeImage " 1 -4)
      ("nbiXPelsPerMeter " 1 -4)
      ("nbiYPelsPerMeter " 1 -4)
      ("nbiClrUsed " 1 -4)
      ("nbiClrImportant " 1 -4)))
(let ((stream (open-binary  "C:\maxheadroom.bmp"))
      (offset 0))
  (format t "Official NametValuen") 
  (dolist (elem bmp-header (format nil "~a bytes read,n see debug screen for details." offset))
    (format t "~a~a" (first elem)
            (case (second elem)
              (0 (string (read-char stream)))
              (1 (read-int stream (third elem)))
              (2 (read-float  stream (third elem)))))
    (setf offset (+ offset (abs (third elem))))))

Copy the code into the Nyquist prompt.
You have to replace the quoted string after ‘open’ with the complete file name.
Note that two backslashes are needed instead of the usual single one.
Press debug to see the values in the debug screen.
After this code, the actual gathering of the sample values would begin.

We can be very open-minded in that regard.
With RGB-24, one byte will represent one colour channel for a pixel.
All the A-Law quantization does is interpreting a byte as 13 bit. This means that brightness and contrast are interpreted differently to the original image.
It is similar to switching from dB-display to linear and back (right mouse button menu).
Our mapping should effectively be 8 bit → 32 bit (float) before the audio goes to the next effect (Reverb or Wah-Wah for instance).