Detailed changes v1.1.5 v1.1.6

From AlsaProject
Jump to: navigation, search

Contents

Detailed changelog between 1.0.28 and 1.1.6 releases

Changelog between 1.0.29 and 1.1.6 releases

alsa-oss

Core

- Release v1.1.6
- Change FSF address (Franklin Street)

Documentation

- Change FSF address (Franklin Street)

Mixer Emulation

- Change FSF address (Franklin Street)

OSS Redirection

- Change FSF address (Franklin Street)

PCM Emulation

- Change FSF address (Franklin Street)

Detailed changelog between 1.1.5 and 1.1.6 releases

Changelog between 1.0.29 and 1.1.6 releases

alsa-lib

Core

- Release v1.1.6
- a set of fixes to reduce gcc warnings
- modules: smixer_python - add support for python3
- conf/ucm: Add chtrt5645-mono-speaker-analog-mic configuration
Add a configuration for Cherry Trail boards which use a rt5645 codec
connected to a mono speaker and with an analog mic on IN2N + IN2P.
The chtrt5645-mono-speaker-analog-mic/HiFi.conf for this is based on the
latest version from https://github.com/plbossart/UCM/tree/master/chtrt5645
with all the unused input options removed and some changes made to make
the analog mic work.
This commit also adds 2 ucm dirs with the longname of 2 boards known to use
this setup, which simply contain a symlink to the generic
chtrt5645-mono-speaker-analog-mic entry.
- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.
- conf/ucm: Add Gigabyte mobo UCM profile with dual HD-audio codecs
Like the previous Lenovo laptops, some Gigabyte mobos have dual
HD-audio codecs and need to switch dynamically via UCM profile.
Reuse the same profile as Lenovo dual codecs, so far.
- conf/ucm: Add dual HD-audio codecs config for Lenovo
Some recent Lenovo laptops have dual codecs and we need to switch them
accordingly. The kernel side already contains a fix and gives the
unique longname string for identifying the board, and here we hook up
the corresponding UCM profile.
The profile was corrected and tested by Hui Wang on Lenovo p520.
Tested-by: Kailang <kailang@realtek.com>
Tested-by: Hui Wang <hui.wang@canonical.com>
- conf/ucm: Rearrange Makefile.am
Just rearrange and split to multiple lines to make future patches
cleaner. No actual code change.
- configure.ac: do not enable alisp code by default
- configure.ac: build extra mixer modules conditionally
- Change snd_dlopen() function to return the error string
The dlopen() function might fail also for another reason than
a missing file, thus return the error string from dlerror().
- Change FSF address (Franklin Street)

Control API

- control ext: fix the default .rawmidi_next_device callback
The previous default settings caused an endless loop.
- control: Proper reference of internal versioned functions
The multiply defined versioned symbols have to be called with
INTERNAL() wrapper.
Add the missing declarations of the internal forms of
snd_ctl_elem_info_get_dimension*() in the local header, and use them
in the (still remaining) callers in alisp.

HWDEP API

- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.

Mixer API

- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.

PCM API

- pcm: ioplug: Implement proper drain behavior
This patch fixes the draining behavior of ioplug in the following
ways:
- When no draining ioplug callback is defined, implement the draining
loop using snd_pcm_wait*() and sync with the drain finishes.
This is equivalent with the implementation in the kernel write().
Similarly as in kernel code, for non-blocking mode, it returns
immediately after setting DRAINING state.
- The hw_ptr update function checks the PCM state and stops the stream
if the draining finishes.
- When draining ioplug callback is defined, leave the whole draining
operation to it. The callback is supposed to return -EAGAIN for
non-blocking case, too.
- When an error happens during draining, it drops the stream, for a
safety reason.
- pcm: Skip avail_min check during draining
snd_pcm_wait() & co checks the current avail value and returns
immediately if it satisfies <= avail_min condition. It's good in
general except for one situation: draining. When the draining is
being performed in the non-blocking mode, apps are supposed to wait
via poll(), typically via snd_pcm_wait(). So this ends up with the
busy loop because of the immediate return from snd_pcm_wait().
A simple workaround is to put the PCM state check and ignore the
avail_min condition if it's DRAINING state. The equivalent check is
found in the kernel xfer code, too.
- a set of fixes to reduce gcc warnings
- pcm: hw: Keep control data from kernel when SND_PCM_APPEND
Without this fix the application pointer would be reseted
whenever an application opens a device with SND_PCM_APPEND.
This would result in an Xrun if the device is already opened and
in running state and the appl_ptr is use.
- pcm: ioplug: update prepare and draining state correctly
PREPARED should only be set when it is done and it was successfully.
DRAINING should be signalled when starting to drain. There is no need to
check if draining was successfully because it will change to drop (SETUP)
in any case.
- pcm: Provide areas_copy function which handles buffer wrap around
The already existing areas_copy functions do not care about the end of
the source and destination buffer.
Therefore the caller has to take care that the requested offset+size
is not exceeding any buffer limit.
This additional function will take care about the end of an buffer
and will continue at the beginning of the buffer.
For example this is required when copying between buffers with
different sizes (not multiple of).
This is often the case in IO plugins like the JACK plugin.
- pcm: ioplug: Provide hw_avail helper function for plugins
This function can be called without calling snd_pcm_avail_update().
The call to snd_pcm_avail_update() can take some time.
Therefore some developers would not like to call it from a real-time
context (e.g. from JACK client context).
- pcm: Do not access lock_enabled if thread safe API
Without this commit compiling fails when THREAD_SAFE_API is not
enabled.
- pcm: ioplug: Use boundary for wrap around
if requested by the IO plugin
Without this changes an IO plugin is not able to report
that buffer_size frames were read from the buffer.
When the buffer was full this is a valid action and
has not to be handled as an under run.
For example when the hw_ptr will be updated with
hw_ptr += buffer_size
and it is using the buffer_size as wrap around
hw_ptr %= buffer_size
would result in the same value as before the add operation.
- pcm: another fix for the snd_pcm_area_silence() fast path
The 64-bit fast path can be used only in limited conditions:
- destination must be aligned to 64-bit (CPU aligned access)
- step must be equal to width
- physical with must be different than 24 (cannot be multiplied to 64)
- pcm: fix a bug to copy silent samples aligned to 64
bits for
24 bit sample cases
A function of 'snd_pcm_area_silence()' has a fast path to copy silent data
efficiently. However, the fast path works well just for a case that target
buffer consists of data samples for which unit of data alignment is
divisors of 64 bits.
At present, the fast path handles sample data aligned to 24 bit. In this
case, the buffer can includes extra 8 bits. This has no issue for 'signed'
case because silent data is zero, however it has an issue for 'unsigned'
case.
This commit fixes the bug by skipping cases of sample data of 24 bit.
- pcm: Fix two bugs in snd_pcm_area_silence()
First, after silencing the buffer 64 bits at a time, any remaining samples
need to be silenced by the following width-specific code. However, instead
of silencing the end of the buffer, the code instead re-silences the start
of the buffer, leaving the end unsilenced. To fix this, update the pointer
used by the width-specific code to point to the end of the area just
silenced, instead of leaving it pointing to the start of the buffer.
Second, the code for 24 bit samples can only silence a single sample, as
there's no loop for multiple samples as with other formats. To fix this,
add a loop similar to the ones used for every other width.
The symptoms of these bugs are random data at the end of every supposedly
silenced buffer with certain format/buffer size combinations, resulting in
pops and noise.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
- pcm: Return the consistent error code for unexpected PCM states
Some PCM functions have the sanity check of the expected PCM states,
and most of them return -EBADFD if the current state doesn't match.
This is bad for some programs like aplay that expect the function
returning a proper code corresponding to the state, e.g. -ESTRPIPE for
the suspend.
This patch is an attempt to address such inconsistencies. The sanity
checker bad_pcm_state() now returns the error code instead of bool, so
that the caller can pass the returned code as is. And it calls a new
helper, pcm_state_to_error(), for obtaining the error code to certain
known PCM error state.
While we're at it, use the new pcm_state_to_error() for simplifying
the existing code to retrieve the error code, too.
Tested-by: Mirza Krak <mirza.krak@gmail.com>
- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.
- timer: Proper reference of internal versioned symbols
The multiply defined versioned symbols have to be called with
INTERNAL() wrapper.
Add the missing declarations of versioned timer API functions in the
local header, and use them in the callers in PCM.
- pcm: fix wrong comments for some cases of linear interpolation of PCM samples
A commit 16b3bf447c28 ('Enhanced bitmasks in PCM - added support for more
formats by Takashi and me') adds support for some cases of linear
interpolation of PCM samples, however some of added comments are not
proper. This commit fixes them.
- pcm: remove unused macros of NORMS_LABELS/NORMS_END
A commit fcd164e6229c ("Permit to PCM plug configuration to specify unchanged
parameters. Added support for RT signals to async interface. Added ops for
PCM mix.") added a pair of NORMS_LABELS/NORMS_END, however they have been
no longer used.
This commit removes them in a point to reduce the amount of code to
maintain.
- pcm: remove unused macros of GETU_LABELS/GETU_END
A commit 07c07da44f27 ("Fixed signess for route conversion") obsoletes
usage of a pair of GETU_LABEL/GETU_END, but it did not remove some
actual codes in 'src/pcm_plugin_ops.h'.
This commit removes them in a point to reduce the amount of code to
maintain.
- pcm: remove unused macros of COPY_LABELS/COPY_END
A commit 7b054f4dce56 obsoleted usage of a pair of COPY_LABELS/COPY_END,
however it did not remove some codes in 'src/pcm/plugin_ops.h'.
This commit removes them in a point to reduce the amount of code to
maintain.
- pcm: plug: add SND_PCM_FORMAT_{S, U}20 to linear_preferred_formats
This commit adds the recently added formats SND_PCM_FORMAT_{S,U}20 to
the linear_preferred_formats array in pcm_plug.
Let's give them lower priority than more standard S24 formats but a higher
priority than less typical 3-byte versions.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
- pcm: linear, route: handle linear formats with 20-bit sample on 4 bytes
The previous patch has added 20-bit PCM formats SND_PCM_FORMAT_{S,U}20 to
alsa-lib.
We need to extend the linear format conversion code with handling of these
sample formats so they can also be utilized by applications that only
recognize the more typical ones like SND_PCM_FORMAT_S16.
Since the conversion arrays are indexed by a format bit width divided by 8
the easiest way to handle these formats is to treat them like they were
40-bit wide (the next free integer multiple of 8 bits).
This doesn't create a collision risk with a future format since there can't
really be a 40-bit sample format that occupies 4 bytes.
Make sure we use the getput conversion method for these formats since a
direct conversion from / to them is not supported.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
- pcm: add and describe SND_PCM_FORMAT_{S, U}20
This patch adds and describes in various functions that query format
properties SND_PCM_FORMAT_{S,U}20 formats that were recently added to the
kernel as SNDRV_PCM_FORMAT_{S,U}20.
These formats are similar to existing 20-bit PCM formats
SND_PCM_FORMAT_{S,U}20_3, however they occupy 4 bytes instead of 3.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
- pcm: route: Fix use_getput flag computation for 3 byte formats
Commit de63b942acf520 ("pcm: route: Use get/put labels for all 3 byte formats")
wanted to make the route plugin use get / put labels not only for 24-bit
physical width formats but also for 18 and 20-bit ones.
There was, however, a typo in that commit so a check for these widths
didn't really work.
Let's fix it now.

Timer API

- timer: Proper reference of internal versioned symbols
The multiply defined versioned symbols have to be called with
INTERNAL() wrapper.
Add the missing declarations of versioned timer API functions in the
local header, and use them in the callers in PCM.

Topology API

- a set of fixes to reduce gcc warnings
- topology: Fix parsing config with multiple hw_configs
Currently, if the config file includes several hw_configs sections,
parse_hw_config_refs() returns after parsing only the first section.
For example, the following config, based on
alsa-lib/src/conf/topology/broadwell/broadwell.conf, is parsed incorrectly:
~~~~
SectionHWConfig."CodecHWConfig" {
id "1"
format "I2S" # physical audio format.
bclk "master" # Platform is master of bit clock
fsync "master" # platform is master of fsync
}
SectionHWConfig."CodecHWConfig2" {
id "2"
format "AC97"
}
SectionLink."Codec" {
# used for binding to the physical link
id "0"
hw_configs [
"CodecHWConfig"
"CodecHWConfig2"
]
default_hw_conf_id "2"
}
~~~~
- topology: Fix to skip writing of header for compound elements
While calculating the size of data to be written into the topology
binary file, the size of the compound elements is added as well. This
results in wrong file offset calculation and topology build failure.
The compound elements shouldn't be written to the topology as these are
already embedded as part of other elements. So, skip adding the size of
compound elements to the file offset size calculation.

ALSA Lisp

- control: Proper reference of internal versioned functions
The multiply defined versioned symbols have to be called with
INTERNAL() wrapper.
Add the missing declarations of the internal forms of
snd_ctl_elem_info_get_dimension*() in the local header, and use them
in the (still remaining) callers in alisp.
- Change FSF address (Franklin Street)

ALSA Server

- a set of fixes to reduce gcc warnings
- Change FSF address (Franklin Street)

Compatibility routines

- Change FSF address (Franklin Street)

Configuration

- conf: USB-Audio: Add second S/PDIF device on Phiree U2SX
Phiree U2SX is the successor of Phiree U2 and has the same unusual
configuration.
See ea865bba4615d906144ae5d4f72a4aad2baffe1f for reference.
- conf/ucm: Add chtrt5645-mono-speaker-analog-mic configuration
Add a configuration for Cherry Trail boards which use a rt5645 codec
connected to a mono speaker and with an analog mic on IN2N + IN2P.
The chtrt5645-mono-speaker-analog-mic/HiFi.conf for this is based on the
latest version from https://github.com/plbossart/UCM/tree/master/chtrt5645
with all the unused input options removed and some changes made to make
the analog mic work.
This commit also adds 2 ucm dirs with the longname of 2 boards known to use
this setup, which simply contain a symlink to the generic
chtrt5645-mono-speaker-analog-mic entry.
- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.
- conf/ucm: Add Gigabyte mobo UCM profile with dual HD-audio codecs
Like the previous Lenovo laptops, some Gigabyte mobos have dual
HD-audio codecs and need to switch dynamically via UCM profile.
Reuse the same profile as Lenovo dual codecs, so far.
- conf/ucm: Add dual HD-audio codecs config for Lenovo
Some recent Lenovo laptops have dual codecs and we need to switch them
accordingly. The kernel side already contains a fix and gives the
unique longname string for identifying the board, and here we hook up
the corresponding UCM profile.
The profile was corrected and tested by Hui Wang on Lenovo p520.
Tested-by: Kailang <kailang@realtek.com>
Tested-by: Hui Wang <hui.wang@canonical.com>
- conf/ucm: Rearrange Makefile.am
Just rearrange and split to multiple lines to make future patches
cleaner. No actual code change.
- configure.ac: build extra mixer modules conditionally
- Change snd_dlopen() function to return the error string
The dlopen() function might fail also for another reason than
a missing file, thus return the error string from dlerror().

Documentation

- Change FSF address (Franklin Street)

Dynamic Loader helpers

- core: Proper reference of internal snd_dlopen()
snd_dlopen() was recently rewritten to be versioned symbols, and we
have to call it with INTERNAL() wrapper from the library itself.
Add the proper declaration in the local header and fix the callers
appropriately.

External PCM I/O Plugin SDK

- pcm: ioplug: Provide hw_avail helper function for plugins
This function can be called without calling snd_pcm_avail_update().
The call to snd_pcm_avail_update() can take some time.
Therefore some developers would not like to call it from a real-time
context (e.g. from JACK client context).
- pcm: ioplug: Use boundary for wrap around
if requested by the IO plugin
Without this changes an IO plugin is not able to report
that buffer_size frames were read from the buffer.
When the buffer was full this is a valid action and
has not to be handled as an under run.
For example when the hw_ptr will be updated with
hw_ptr += buffer_size
and it is using the buffer_size as wrap around
hw_ptr %= buffer_size
would result in the same value as before the add operation.

Kernel Headers

- asound.h: add SNDRV_PCM_FORMAT_{S, U}20
This patch adds definitions of 20-bit, 4-byte PCM formats
SNDRV_PCM_FORMAT_{S,U}20, that were recently added to the kernel, to
alsa-lib's own copy of asound.h.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

Simple Abstraction Mixer Modules

- modules: smixer_python - add support for python3
- configure.ac: build extra mixer modules conditionally
- Change snd_dlopen() function to return the error string
The dlopen() function might fail also for another reason than
a missing file, thus return the error string from dlerror().

Test/Example code

- test: correct emulation for channel-map TLV
Current implementation of channel-map TLV on test program is not valid.
Furthermore, it brings buffer-over-run due to byte counting.
This commit fixes it.

alsa-utils

Core

- Release v1.1.6

ALSA Control (alsactl)

- alsactl: Only start restore service when asoundrc file exists
This solves the chicken and egg problem on fresh installations whereby
the alsa state file does not yet exist, and alsa-restore unit attempted
to launch without first having a state file.
- Change FSF address (Franklin Street)

ALSA RawMidi Utility (amidi)

- Change FSF address (Franklin Street)

Speaker Test

- speaker-test: Refactor the tone-generator codes
There are many redundant open codes in speaker-test for performing the
similar things, and especially the tone generator codes are ugly.
Let's clean up a bit. This patch combines all open-codes into a
single common helper with the callback for generating the tone.

alsaloop

- alsaloop: fix a typo in the comparison
Hello maintainers,
I would like to suggest you a patch which fixes a typo in the alsa-utils
alsaloop.
Best Regards,
Kirill Marinushkin
- Change FSF address (Franklin Street)

amixer

- Change FSF address (Franklin Street)

aplay/arecord

- aplay: Fix wav file not being split on 32 bit platforms
On my 32 bit armhf board arecord exits because of write() returning EFBIG
when the output file size reaches 2147483647 bytes.
To fix this, include generated header file before system header files
so that _FILE_OFFSET_BITS=64 is used properly, as required in documentation
"man feature_test_macros".
- aplay: Adjust sample rate limits to support newer hardware
There are number of devices that support up to 384 kHz sampling rate and
some devices up to 768 kHz sampling rate. This patch increases sanity
check limit to 768k in order to support testing of such hardware.

bat (basic audio tester)

- bat: alsa.c - move the thread cleanup pop before goto exit3

alsa-tools

Core

- Release v1.1.6
- Makefile: fix version file creation

Digigram Echo Mixer

- echomixer: add .desktop and icon files
- Change FSF address (Franklin Street)

Envy24 Control

- envy24control: add .desktop and icon files
- Change FSF address (Franklin Street)

HDA Jack Retask

- hdajackretask: add .desktop and icon files

HDA Jack Sense Test

- hdajacksensetest: add gitcompile to EXTRA_DIST
The gitcompile script is used from the top-level Makefile, so it needs
to be included in the tarball.

as10k1 (EMU10K1+ DSP Assembler)

- Change FSF address (Franklin Street)

hdspconf

- hdspconf: move .desktop and icon files to desktop, use modern destination for icons
- hdspconf, hdspmixer: validate the .desktop files

hdspmixer

- hdspmixer: move .desktop and icon files to desktop, use modern destination for icons
- hdspconf, hdspmixer: validate the .desktop files

hwmixvolume

- hwmixvolume: add .desktop and icon files
Resized version of public domain clipart found here:
http://www.openclipart.org/detail/17428
- hwmixvolume: use python2 directly

alsa-plugins

Core

- Release v1.1.6
- Change FSF address (Franklin Street)

A52 Output plugin

- Change FSF address (Franklin Street)

Arcam AV control plugin

- Change FSF address (Franklin Street)

Jack PCM plugin

- jack: Use correct parameter order for snd_pcm_areas_silence()
Without this fix it will sometimes fail with a segmentation fault.
- jack: Report Xruns to user application
Only increasing the hw_ptr is not sufficient
because it will not be evaluated by the ALSA library
to detect an Xrun.
In addition there is a raise where an Xrun detected by the JACK thread
could not be detected in the ALSA thread.
- In playback use case
- The hw_ptr will be increased by the JACK thread
(hw_ptr > appl_ptr => Xrun)
- But the ALSA thread increases the appl_ptr before evaluating the
hw_ptr
- Therefore the hw_ptr < appl_ptr again
- ALSA will not detect the Xrun which was already detected by the
JACK thread
Therefore an additional variable is required to report an Xrun from the
JACK thread to ALSA.
- jack: Do not Xrun the ALSA buffer
when the JACK thread is requesting too many audio frames
Playback:
Without this commit the ALSA audio buffer will be played with endless
repeats as long as the user application has not provided new audio data.
Therefore this garbage will be played as long as the user application has
not called snd_pcm_stop() after an Xrun. With this fix the rest of the
JACK buffer will be filled with silence.
Capture:
Without this commit the audio data in the ALSA buffer would be
overwritten. With this commit the new data from the JACK buffer will not
be copied. Therefore the existing data in the ALSA buffer will not be
overwritten.
- jack: Use boundary as hw_ptr wrap around
instead of using buffer_size as wrap around.
This is required to detect Xruns.
It is also required to allow the JACK thread
to processes the whole ALSA audio buffer at once
without calling snd_pcm_avail_update() in between.
For example when the hw_ptr will be updated with
hw_ptr += buffer_size
and it is using the buffer_size as wrap around
hw_ptr %= buffer_size
would result in the same value as before the add operation.
Due to that the user application would not recognize
that the complete audio buffer was copied.
- jack: Write only valid values to the internal hw_ptr
Otherwise the ALSA thread could for example read a hw_ptr >
buffer_size
- Change FSF address (Franklin Street)

tinycompress

Core

- Release v1.1.6

Utilities

- cplay: make get_codec_iec return void
get_codec_iec() doesn't return anything, so make return type as void
- cplay: support IEC61937 format
This patch adds very simple supports for IEC61937 S/PDIF format.
The cplay just specifies the format ID and sends audio data to ALSA.
There is no check the audio data is valid or invalid as IEC61937
specifications.
- cplay: move around MP3 header parsing method
This patch moves MP3 parsing method for -I option, this is for
adding other codec ID in the future.
- cplay: add option to specify codec ID
This patch adds a -I command line option to set the codec ID,
same as crecord.
- cplay: fix size and nmemb of mp3 header of fread
This patch swaps 'size' and 'nmemb' arguments of fread.
The fread returns always 1 (because 'nmemb' is 1) so checking
the return value is always failure.

Detailed changelog between 1.0.29 and 1.1.6 releases

Changelog between 1.0.29 and 1.1.6 releases

alsa-python

Core

- Release v1.1.6
- setup: add some missing fields, add header files from pyalsa to MANIFEST
- setup.py: check for the existence of the build directory
- common.h: fix InternFromString()

Documentation

- Change FSF address (Franklin Street)

Test python scripts

- hctltest2: use 'hw:0' device instead 'default'

pyalsa.alsacard module

- initial python3 support
- Change FSF address (Franklin Street)

pyalsa.alsacontrol module

- fix tp_free() calls, remove wrong PyObject_GC_Del use
- initial python3 support
- Change FSF address (Franklin Street)

pyalsa.alsahcontrol module

- fix tp_free() calls, remove wrong PyObject_GC_Del use

pyalsa.alsaseq module

- alsaseq: simplify TCONSTADD
Custom Search
Personal tools
Namespaces

Variants
Actions
Navigation
wiki
Toolbox