Onda is a Java application that compresses 16-bit and 24-bit AIFF and WAVE audio files with the Onda lossless audio compression (LAC) algorithm. The Onda algorithm doesn't perform as well as some other open-source LAC algorithms in terms of either speed or compression ratio; its virtue, if it can be said to have one, is that it is easy to understand and to implement, involving no mathematics beyond a bit of arithmetic.
Onda has the following features:
bext
chunk used in BWF files), using a filter to specify the chunks that should be included
in or excluded from a compressed file.
Onda is made available under two licences:
uk.blankaspect.onda
package (including resources) may
be used under the terms of version 3 of the GNU General Public License.
This section assumes that you have some experience of building and running a Java application.
A Java Development Kit (JDK) that supports Java 17, such as Eclipse Temurin from Adoptium, is required to build Onda.
The src
directory of the repository contains all the source code and
resources that constitute the application; there are no external dependencies. The
directory conforms to the Maven standard directory layout: the source code is in
src/main/java
and the resources are in src/main/resources
.
The supplied Kotlin-DSL-based Gradle
build script, build.gradle.kts
, modifies the compileJava
and
jar
tasks (provided by the java
plug-in) to compile the
application and to create an executable JAR file for it.
The supplied Kotlin-DSL-based Gradle build script, build.gradle.kts
,
defines two tasks that may be used to run Onda:
compileJava
task.
jar
task.
Both tasks extend the JavaExec
task.
The Onda application can be run in two modes, referred to in this document as console mode and GUI mode. The main operations (compress, expand and validate) are available in both modes.
Onda decides on its mode — whether to run as a console application or as a GUI
application — when it starts up: if the application has command-line arguments, it
will run as a console application unless one of the arguments specifies a GUI;
otherwise, it will run with a GUI. The command-line arguments that determine the mode
are the arguments to the Onda application, not the options for the java
launcher. (The application's arguments come after the name of the Onda JAR file in
the command line that invokes the java
launcher.)
When it starts up, Onda is configured with configuration properties that are read from two sources: the command line of the Java launcher and a configuration file whose location may be explicitly specified. If the same property is specified on the command line and in a configuration file, the value from the configuration file takes precedence.
The recommended method of setting the properties in a configuration file is with the Preferences command. For command-line properties, which must be edited manually, the form of the property values is given in an appendix, and it can also be inferred by generating a configuration file with the desired values and inspecting the contents of the file.
When Onda is run, configuration properties may be passed to the java
launcher on the command line as system properties; eg,
-Dapp.general.mainWindowLocation="100, 0"
. Onda's
command-line configuration properties all have the prefix app.
. A list of
all the properties that are recognised by Onda is given in an appendix.
System properties can be added to the two supplied Gradle
tasks, runMain
and runJar
, with the
systemProperties(Map<String, ?>)
method.
One particular property, app.configDir, is used to specify the directory that contains a configuration file, as described below.
The configuration file is named onda-config.xml
. Onda doesn't require
a configuration file: it uses a default value for any configuration property that is
missing from the source(s) of configuration. Similarly, if it finds a property value to
be invalid, Onda will display a message to this effect and use the default value of the
property. If the configuration file contains a property that was specified on the
command line, the value from the configuration file is used.
If the configuration has changed when you exit the application normally (ie, using the Exit command or an equivalent), Onda will save its configuration to a configuration file. If a configuration file was read on startup, it will overwrite that file; otherwise, it will write a configuration file to the default directory described above, unless the value of the app.configDir property was an empty string.
A configuration file can be written explicitly with the Save configuration command within the Preferences dialog.
When it starts up, Onda is informed of the location of the configuration file with the app.configDir property. The value of the property may contain special constructs for system properties, environment variables and the user's home directory.
The app.configDir property may be set in two ways:
java
launcher, or
onda-properties.xml
that resides in the same directory as
the onda.jar
JAR file.
The onda-properties.xml
file is a legacy from the time when Onda was
distributed as a JAR file with an installer; the properties file was written by the
installer. If you create a properties file, it should have the following form, with the
example pathname replaced by the actual pathname:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <entry key="app.configDir">/home/slothrop/.blankaspect/onda</entry> </properties>
If the app.configDir property is set both on the command line and in the properties file, the value in the properties file takes precedence.
The existence and value of the app.configDir property determines the locations that are searched for a configuration file:
$PWD
on Linux/UNIX systems, depends on the system and the way in
which Onda was run.
$HOME/.blankaspect/onda
, where $HOME
is the
environment variable that denotes the user's home directory. On Windows
systems, the default directory is %APPDATA%\blankaspect\onda
, where
%APPDATA%
is an environment variable.
Onda runs in console mode if command-line arguments are passed to it when it starts up.
Valid arguments are of three types: options, commands and input pathnames. Options and
commands must have --
prefixed to them; there are no single-character short
forms that have a prefix of a single hyphen. The name and value of an option may be
separated with whitespace or with a =
character.
In keeping with convention, the command-line syntax for the Onda application (shown
below and in response to Onda's --help
command) implies that the
application is invoked with the command onda. However, this is only a
convention; the actual form of a command line that invokes Onda is described in the
relevant sections for Linux/UNIX and Windows.
+
|−
)chunk-ids+
|−
)chunk-ids+
or −
prefixed to them:
+
, the filter is inclusive: a chunk is
preserved if its ID is in chunk-ids.
−
, the filter is exclusive: a chunk
is preserved if its ID is not in chunk-ids.
+
or −
is
taken to be the separator between the identifiers listed in
chunk-ids. Trailing spaces are assumed for any identifier that has
fewer than four characters.
--wave-chunk-filter=+/bext/cue
preserves chunks in a
WAVE file with IDs bext
and cue
;
--aiff-chunk-filter=−
preserves all the
ancillary chunks in an AIFF file (ie, excludes none) (the default);
--wave-chunk-filter=+
discards all the ancillary
chunks in a WAVE file (ie, includes none).
--recursive
option is specified, the
directory structure below the input directory will be reproduced in the
output directory.
none
|title
|log
|result
|all
}
,
. The default value is
log,result
.
=
.
@
, it denotes a file that contains
a list of input pathnames and, optionally, output directories. Each non-empty line
of the file is expected to contain a single input pathname, which may be followed by
one or more tab characters (U+0009) and the pathname of an output directory.
?
and
*
.
+
, the prefix is ignored. The
prefix can be used to prevent the expansion of patterns such as *
on
the Java command line and to allow pathnames that start with a literal
@
. A literal +
at the start of a pathname must be escaped
by prefixing +
to it.
${
and }
; eg, ${HOME}. A Java system property
takes precedence over an environment variable with the same name. A Java system
property can be specified by prefixing sys.
to it (eg,
${sys.user.home}), and an environment variable can be specified by prefixing
env.
to it (eg, ${env.HOME}).
The three main commands — Compress, Expand and Validate — are described in the section on commands.
The main window of the Onda application in GUI mode is equivalent to a dialog box. The size of the window cannot be changed directly, though it can be changed indirectly (for example, by changing the fonts in the user preferences).
The Input file or directory combo box, the Input mode drop-down list and the Recursive check box are used together to specify the input files or directories of a Compress, Expand or Validate command. You can specify a pathname in the Input file or directory combo box by any of the following methods:
.aif
, .aiff
, .wav
or
.wave
are processed; for the Expand and
Validate commands, files with the filename suffix
.onda
are processed. If the Recursive
check box is selected, all appropriate files in directories below the specified
directory are processed too.
If the Input file or directory field is empty, the Compress, Expand and Validate commands will each display a file-selection dialog to allow you to choose the input file.
The Output directory combo box specifies the directory to which the output files of the Compress and Expand commands will be written. If the field is empty, each output file will be written to the same directory as its input file. (The Output directory field is ignored by the Validate command.) You can specify a pathname in the Output directory combo box by the methods described above for the Input file or directory combo box.
The arrow buttons alongside the Input file or directory combo box and the Output directory combo box allow you to copy a pathname from one combo box to another.
During compression, expansion or validation, the progress of the operation is shown in a separate dialog box. A configuration property, appearance.showOverallProgress, determines whether the dialog box shows the overall progress of the operation when processing multiple files.
The six buttons at the bottom of the main window are associated with the main commands.
If your system supports the dragging and dropping of files (for example, from a file manager such as GNOME Nautilus or Windows Explorer), there are three areas of the main window of Onda that you can drag and drop files or directories onto: the Input file or directory combo box, the Output directory combo box, and the remaining area of the window, referred to as the main panel.
The Input file or directory combo box and the Output directory combo box will both accept the dragging and dropping of a single file or directory, whose pathname will be displayed in the field of the combo box. When you drag a file or directory onto one of the combo boxes, take care that you don't drop it onto the main panel.
The main panel will accept the dragging and dropping of multiple files, which will
initiate a sequence of compression and expansion operations on the files that were
dropped, according to the suffix of each filename: files with the .onda
suffix will be expanded; other files will be compressed if they have one of the
supported audio file formats. Any directory that is dropped onto the main panel will be
ignored. Before the compression and expansion operations begin, you will be asked to
confirm that you want to proceed.
This section describes the commands that are available in GUI mode, which are issued from the buttons in the main window. The first three commands — Compress, Expand and Validate — are also available in console mode.
The Compress command compresses each valid input file using
the Onda algorithm with the block length denoted by the compression.blockLength configuration property or
a default block length of 256. The name of the output file is the name of the input
file with an additional .onda
suffix. If an output directory is specified,
all output files are written to that directory; otherwise, each output file is written
to the same directory as its input file. If the input pathname is a directory and the
recursive option is selected, the directory structure below the input directory
is reproduced in the output directory.
The type (AIFF or WAVE) of an input file is inferred from the suffix of its filename: a
file with the suffix .aif
or .aiff
is assumed to be an AIFF
file, and a file with the suffix .wav
or .wave
is assumed to
be a WAVE file. If the filename suffix is not recognised, the first few bytes of the
file are read to determine its type. An error occurs if the file type that is implied
by the filename suffix does not correspond to the actual file type.
A WAVE file may contain either PCM (raw) sample data or sample data that have already been compressed with a lossless or lossy compression algorithm such as one of the MPEG audio algorithms. An AIFF file (as distinct from an AIFF-C file) can contain only raw sample data. Onda can compress only files that contain raw sample data.
In GUI mode, the result of a compression operation (including the compression ratio and the time taken) is written to an internal log, which can be displayed with the View log command. In console mode, the information is written to the console.
An AIFF file is an instance of an IFF file, and a WAVE
file is an instance of an RIFF file. Both types
of file consist of a number of chunks; each chunk has a 4-byte ASCII identifier
(ID). An AIFF file must have at least a Common chunk (ID =
"COMM
") and a sound data chunk (ID =
"SSND
"), whereas a WAVE file, if it contains raw sample data,
must have at least a Format chunk (ID = "fmt
") and a sound
data chunk (ID = "data
"). Both types of file may have other,
ancillary chunks, some of which extend the file format in ways that are essential to a
particular application. For example, files of the Broadcast Wave Format (BWF) —
an extension to the WAVE format — include a chunk with the ID
"bext
", which contains, among other things, information that is
used to synchronise the BWF file with other audio or video sources. Such chunks need to
be preserved in order to maintain the usefulness of the original audio file.
You can specify, by means of a filter, the ancillary chunks that will be preserved when an AIFF or WAVE file is compressed. (The critical Common/Format and data chunks are always preserved.) A filter is specific to one file type, AIFF or WAVE. It comprises a set of chunk IDs, and is either inclusive or exclusive. When a file is compressed, a chunk is preserved if its ID is contained in an inclusive filter or not contained in an exclusive filter. In console mode, a filter can be specified as a command-line option; if no filter is specified, all ancillary chunks are preserved. In GUI mode, the filter is selected from a list of filters in a configuration file, and the filter properties can be edited from within the Preferences dialog.
The preserved chunks are merged, then compressed with Java's built-in zlib compression library, which uses the DEFLATE algorithm. When an Onda file is expanded, the chunks are restored in the order in which they appeared in the original file. A list of preserved chunks is written to the log in GUI mode, or to the console in console mode.
Onda files that contain preserved chunks have a different version number from those that don't contain preserved chunks, which prevents them from being expanded or validated by version 1.0 of the Onda application.
The Expand command decompresses files that have been
compressed with the Onda application. If the input filename has the suffix
.onda
, the name of the output file is the name of the input file with its
.onda
suffix removed; otherwise, the name of the output file is the name of
the input file with a numerical suffix appended to its filename stem. If an output
directory is specified, all output files are written to that directory; otherwise, each
output file is written to the same directory as its input file. If the input pathname
is a directory and the recursive option is selected, the directory structure
below the input directory is reproduced in the output directory.
The type (AIFF or WAVE) of an output file is inferred from the suffix of the name of the
input file after the .onda
suffix has been removed: a file with the suffix
.aif
or .aiff
is assumed to be an AIFF file, and a file with
the suffix .wav
or .wave
is assumed to be a WAVE file. If the
filename suffix is not recognised, the file type is determined from the ancillary chunks
of the original file that were preserved in the Onda file. If the file type cannot be
determined by either of these methods, you will be asked to select it. An error occurs
if the file type that is implied by the filename suffix does not correspond to the file
type of any preserved chunks.
In GUI mode, the result of an expansion operation is written to an internal log, which can be displayed with the View log command. In console mode, the information is written to the console.
The Validate command tests the validity of files that have been compressed with the Onda application. It is intended to allow the integrity of archives to be checked without the need to decompress each file. It validates the sample data, along with the data from any ancillary chunks in the original file that were preserved during compression.
In GUI mode, the result of a validation operation is written to an internal log, which can be displayed with the View log command. In console mode, the information is written to the console.
In GUI mode, Onda maintains an internal log of the result of Compress, Expand and Validate commands; the View log command displays this log in a dialog box. Within the log dialog, the Clear command (Alt+X) deletes the entire contents of the log, and the Copy command (Alt+C) copies the contents of the log to the system clipboard so that it can be pasted into another application. A portion of the log can be copied to the clipboard from the text area of the log dialog by selecting the text with the mouse cursor and pressing Ctrl+C.
In the log, error messages have !
prefixed to them.
The Preferences command brings up a tabbed dialog box in which the configuration properties of Onda can be edited. The properties on the various tabbed pages are described below.
Some of the configuration properties in the Preferences dialog are edited with a spinner — a graphical component that consists of a text field adjacent to a pair of small buttons. The value in the text field may be edited manually, or it may be incremented and decremented by one of the following methods:
Using the last two methods, the amount by which the value is incremented or decremented can be modified by holding down the Ctrl, Shift or Ctrl+Shift keys, which correspond to increments of 10, 100 and 1000 respectively.
Yes
, the alphabetic case of filenames will be ignored
when matching filenames (eg, the pattern *.txt
will match the
filenames foo.txt
and BAR.TXT
). This property is used
only to determine whether the case of the appropriate filename suffix
(.wav
or .onda
) is ignored when searching a directory
for input files.
No
.
Yes
, pathnames are displayed in a reduced
"UNIX style" in some parts of the GUI and in output to the console.
A pathname is converted from its platform-specific form in two steps:
~
.
\
on Windows systems) is replaced
by /
.
No
.
Yes
, all the text in a text field will be
automatically selected when the field gains keyboard focus, regardless of how
the focus is transferred.
Yes
.
Yes
, the location of the main window on the screen
will be saved to the configuration file when you exit the application. The next
time that Onda is run, its main window will be positioned at the previously
saved location.
No
.
awt.useSystemAAFontSettings
.
Default
.
No
, the dialog box shows only
the progress of each file during operations on multiple files. If you select
Yes
, the dialog box shows the overall progress of an operation on
multiple files in an additional progress bar, and the time fields show the
overall time rather than the time for each file. Operations are slightly slower
if the overall progress is shown.
Yes
.
+
on a green
background, which denotes an inclusive filter, or a −
on a
red background, which denotes an exclusive filter. The chunk identifiers that
comprise a filter are shown as a comma-separated list with trailing spaces
removed. (A comma is a legal character in an identifier; if any identifiers
contain commas, the comma-separated list of identifiers may be misleading.)
Some of the configuration properties will take effect when the Preferences dialog is accepted (by closing it with OK); other properties (eg, the look-and-feel and fonts) will not take effect until the next time that Onda is run.
The configuration file is normally saved automatically when Onda exits, if the configuration has changed. The Save configuration command in the Preferences dialog can be used to save a configuration file explicitly.
This command terminates the application.
Where indicated elsewhere in this document, pathname properties in Onda can contain special constructs for system properties, environment variables and the user's home directory. The special constructs are expanded when the pathname is used.
user.home
)
and environment variables (eg, PATH
) are referenced by enclosing them
between ${
and }
; that is, they must have the form
${<name>}
. A Java system property takes precedence over an
environment variable with the same name.
${user.home}/projects
${HOME}/projects
sys.
to it.
${sys.user.home}/projects
env.
to it.
${env.HOME}/projects
~
in a pathname is expanded into the user's home directory
using the user.home
system property, which is usually equivalent to the
environment variable $HOME
on Linux/UNIX systems or
%USERPROFILE%
on Windows systems.
~/projects
The table below lists the configuration properties of Onda. Apart from the app.configDir property, which, for obvious reasons, cannot
be used within a configuration file, and the chunkFilter
properties, which
are ignored if they are given as command-line properties, all properties can be used in
the two configuration locations: command-line properties and configuration file.
When used in a -D
command-line property, app.
must be prefixed
to the property key (eg, app.general.mainWindowLocation).
The <index> of an indexed property key (eg, chunkFilter.aiff.filter) is a three-digit decimal-string representation of the zero-based index of the property (eg, the third AIFF chunk filter is chunkFilter.aiff.filter.002).
Any commas (,
) or backslash characters (\
) in the name of a
font must be escaped by prefixing a \
character to them.
In the table below, the initial character of an italicised component of a property value denotes its data type according to the following convention:
i | integer |
p | platform-specific pathname, which may contain special constructs |
s | string |
Property key | Property value |
---|---|
configDir | pPathname |
appearance.lookAndFeel | sName |
appearance.showOverallProgress | false | true |
appearance.textAntialiasing | default | none | normal | subpixelHRgb | subpixelHBgr | subpixelVRgb | subpixelVBgr |
chunkFilter.aiff.filter.<index> | sFilter |
chunkFilter.aiff.index | iFilterIndex |
chunkFilter.wave.filter.<index> | sFilter |
chunkFilter.wave.index | iFilterIndex |
compression.blockLength | iNumSampleFrames |
font.comboBox | sName, plain | bold | italic | boldItalic, iSize |
font.main | sName, plain | bold | italic | boldItalic, iSize |
font.textArea | sName, plain | bold | italic | boldItalic, iSize |
font.textField | sName, plain | bold | italic | boldItalic, iSize |
general.ignoreFilenameCase | false | true |
general.mainWindowLocation | iX, iY |
general.selectTextOnFocusGained | false | true |
general.showUnixPathnames | false | true |
path.compress | pPathname |
path.expand | pPathname |
path.validate | pPathname |
There is a link to a document containing details of the Onda compression algorithm and the formats, old and new, of the compressed files produced by the Onda application on Onda project page.