File jack-example-tools-1.obscpio of Package jack-example-tools

07070100000000000081A400000000000000000000000161E2F7EE00000627000000000000000000000000000000000000002100000000jack-example-tools-1/.cirrus.ymltask:
  freebsd_instance:
    matrix:
      - image_family: freebsd-12-3
      - image_family: freebsd-13-0

  environment:
    CFLAGS: -O2 -pipe -fPIC -fstack-protector-strong -fno-strict-aliasing -I/usr/local/include
    CPPFLAGS: -O2 -pipe -fPIC -fstack-protector-strong -fno-strict-aliasing -I/usr/local/include
    LDFLAGS: -lreadline -L/usr/local/lib -fstack-protector-strong

  # Install jack2 from source - replace by package once 1.9.20 is out.
  jack2_dependencies_script:
    - pkg install -y pkgconf python3 libsndfile libsamplerate libsysinfo readline alsa-lib dbus expat opus git
  jack2_source_script:
    - git clone --branch develop --depth 1 https://github.com/jackaudio/jack2.git /jack2
  jack2_config_script:
    - cd /jack2 && python3 ./waf configure --celt=no --sndfile=yes --samplerate=yes --alsa=yes --dbus --classic --autostart=dbus --readline=yes --opus=yes --example-tools=no --prefix /usr/local --pkgconfigdir libdata/pkgconfig
  jack2_build_script:
    - cd /jack2 && python3 ./waf
  jack2_install_script:
    - cd /jack2 && python3 ./waf install

  prepare_script:
    - mkdir /Install
  dependencies_script:
    - pkg install -y pkgconf python3 libsndfile libsamplerate libsysinfo readline alsa-lib zita-alsa-pcmi zita-resampler opus meson ninja
  config_script:
    - meson --prefix /Install --mandir man --buildtype release --strip build
  build_script:
    # Workaround for missing alloca headers - remove when resolved.
    - touch build/tools/alloca.h
    - ninja -C build
  install_script:
    - DESTDIR="/Install" meson install -C build
07070100000001000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000001D00000000jack-example-tools-1/.github07070100000002000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000002700000000jack-example-tools-1/.github/workflows07070100000003000081A400000000000000000000000161E2F7EE0000054D000000000000000000000000000000000000003100000000jack-example-tools-1/.github/workflows/build.yml---

name: Build on various Operating Systems

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build_arch_linux_jack1:
    runs-on: ubuntu-latest
    container:
      image: archlinux:latest
    steps:
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: pacman --noconfirm -Syu alsa-lib base-devel celt meson opus readline libsamplerate libsndfile zita-alsa-pcmi zita-resampler
      - name: Install jack1
        run: |
          printf "[pro-audio]\nServer = https://pkgbuild.com/~dvzrv/repos/pro-audio/\$arch\n" >> /etc/pacman.conf
          pacman -Syy
          pacman --noconfirm -S jack
      - name: Build jack-example-tools
        run: meson build && ninja -C build
      - name: Install jack-example-tools
        run: ninja -C build install
  build_arch_linux_jack2:
    runs-on: ubuntu-latest
    container:
      image: archlinux:latest
    steps:
      - uses: actions/checkout@v2
      - name: Install dependencies
        run: pacman --noconfirm -Syu alsa-lib base-devel celt meson opus readline libsamplerate libsndfile zita-alsa-pcmi zita-resampler
      - name: Install jack2
        run: pacman --noconfirm -S jack2
      - name: Build jack-example-tools
        run: meson build && ninja -C build
      - name: Install jack-example-tools
        run: ninja -C build install
07070100000004000081A400000000000000000000000161E2F7EE00000241000000000000000000000000000000000000002F00000000jack-example-tools-1/.github/workflows/irc.ymlname: irc

on: [push]

jobs:
  notification:
    runs-on: ubuntu-latest
    name: IRC notification
    steps:
      - name: Format message
        id: message
        run: |
          message="${{ github.actor }} pushed $(echo '${{ github.event.commits[0].message }}' | head -n 1) ${{ github.event.commits[0].url }}"
          echo ::set-output name=message::"${message}"
      - name: IRC notification
        uses: Gottox/irc-message-action@v2
        with:
          channel: '#jack'
          nickname: jackaudio-bot
          message: ${{ steps.message.outputs.message }}
07070100000005000081A400000000000000000000000161E2F7EE00000008000000000000000000000000000000000000002000000000jack-example-tools-1/.gitignore/build/
07070100000006000081A400000000000000000000000161E2F7EE00000458000000000000000000000000000000000000002200000000jack-example-tools-1/CHANGELOG.md# Changelog

## [Unreleased]

### Added

### Changed

### Deleted

## [1]

### Added
- Add legacy [example-clients](https://github.com/jackaudio/example-clients)
  and [tools](https://github.com/jackaudio/tools)
- Add man pages for example-clients and tools from
  [jack2](https://github.com/jackaudio/jack2)
- Add jack2-only example-clients
- Add license files for example-clients and tools and imported zalsa files
- Add meson build system
- Add CI builds against jack1 and jack2 in an Arch Linux container
- Add supported jack version to project description: jack1 (>=0.126.0), jack2
  (>=1.9.20), pipewire-jack (>=0.3.44)
- Add support to compile against different jack implementations based on
  available features and function definitions

### Changed
- Consolidate example-clients and tools with the versions in
  [jack2](https://github.com/jackaudio/jack2)
- Apply commits from open pull requests in
  [example-clients](https://github.com/jackaudio/example-clients) and
  [tools](https://github.com/jackaudio/tools)
- Make target executables and libraries compatible with jack1 and jack2 (if
  possible)
07070100000007000081A400000000000000000000000161E2F7EE000006E1000000000000000000000000000000000000002500000000jack-example-tools-1/CONTRIBUTING.md# Contributing Guidelines

These are the contributing guidelines for jack-example-tools.
All contributions, unless noted otherwise, are licensed under the terms of the
GPL-2.0-or-later (see [LICENSE](LICENSE)).
Contributions to the [tools/zalsa/](tools/zalsa/) are licensed under the terms
of the GPL-3.0-or-later (see [tools/zalsa/LICENSE](tools/zalsa/LICENSE)).

Problems with and feature requests for the project may be reported in the
[issue tracker](https://github.com/jackaudio/jack-example-tools/issues).

Changes to the code-base can be provided via [pull
requests](https://github.com/jackaudio/jack-example-tools/pulls).

## Continuous Integration

The project is built in a [continuous integration
(CI)](https://github.com/jackaudio/jack-example-tools/actions) pipeline handled
by github actions upon pull request and push to the default branch. The
integration aims at covering all jack implementations on as many operating
systems as possible.

Changes to the project may only be merged if the CI finishes successfully.

## Releases

New releases are created by

* adding a commit that
  * updates the project version in [meson.build](meson.build)
  * updates the [changelog](CHANGELOG.md) to the current version while adding a
    new (empty) subsection for `[Unreleased]` modifications with `Added`,
    `Changed` and `Deleted` subsubsections.
* tagging the commit using a signed tag (i.e. `tag -s <VERSION>`) according to
  the new project version

### Versioning

The project's version is defined as `<MAJOR>` (e.g. `1` or `2`), which is
reflected both in the build system and the tag.

## Testing

Contributors are expected to test their changes to the project on as many
operating systems as available to them *before* opening a pull request.
07070100000008000081A400000000000000000000000161E2F7EE00003B74000000000000000000000000000000000000001D00000000jack-example-tools-1/LICENSE                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS
07070100000009000081A400000000000000000000000161E2F7EE00000BF4000000000000000000000000000000000000001F00000000jack-example-tools-1/README.md# JACK example tools

This repository holds the official JACK example clients and tools, which have
been tracked in the
[example-clients](https://github.com/jackaudio/example-clients) and
[tools](https://github.com/jackaudio/tools) repositories in the past.

## Dependencies

The project requires the following dependencies:

* [alsa-lib](https://www.alsa-project.org/wiki/Main_Page) (required when
  building `alsa_in` and `alsa_out` or ZALSA internal clients)
* [jack1](https://github.com/jackaudio/jack1) >= 0.126.0,
  [jack2](https://github.com/jackaudio/jack2) >= 1.9.20, or
  [pipewire-jack](https://gitlab.freedesktop.org/pipewire/pipewire) >= 0.3.44
  (other versions may work but are not supported)
* [opus](https://www.opus-codec.org/) (optional buildtime/ runtime dependency
  for `jack_netsource`)
* [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) (optional
  buildtime/ runtime dependency for `jack_transport`)
* [libsamplerate](https://libsndfile.github.io/libsamplerate/) (required when
  building `alsa_in` and `alsa_out` or `jack_netsource`)
* [libsndfile](https://libsndfile.github.io/libsndfile/) (required when
  building `jack_rec`)
* [libzita-alsa-pcmi](https://kokkinizita.linuxaudio.org/linuxaudio/) (required
  when building ZALSA internal clients)
* [libzita-resampler](https://kokkinizita.linuxaudio.org/linuxaudio/) (required
  when building ZALSA internal clients)

For all available options please refer to
[meson_options.txt](meson_options.txt) or run `meson configure` in the project
directory.

## Building

jack-example-tools uses the [meson build system](https://mesonbuild.com).

To configure the project, meson's [universal
options](https://mesonbuild.com/Builtin-options.html#universal-options) (e.g.
**--prefix**) can be used to prepare a build directory:

```bash
meson --prefix=/usr build
```

To build the applications and libraries [ninja](https://ninja-build.org/) is
required:

```bash
ninja -C build
```

## Installing

Meson is able to install the project components to the system directories (when
run as root), while honoring the **DESTDIR** environment variable:

```bash
DESTDIR="/some/other/location" meson install -C build
```

## Releases

[Releases of
jack-example-tools](https://github.com/jackaudio/jack-example-tools/tags) are
created by its current maintainer [Filipe Coelho](https://github.com/falktx)
(`62B11043D2F6EB6672D93103CDBAA37ABC74FBA0`).

To verify a tag, first import the relevant PGP key:

```
gpg --auto-key-locate wkd,keyserver --search-keys falktx@falktx.com
```

Afterwards a tag can be verified from a clone of this repository:

```
git verify-tag <tag>
```

## License

All files (unless noted otherwise) are licensed under the terms of the
**GPL-2.0-or-later** (see [LICENSE](LICENSE)).

The code in [tools/zalsa](tools/zalsa) is provided via [Fons Adriansen's
zita-ajbridge](https://kokkinizita.linuxaudio.org/linuxaudio/zita-ajbridge-doc/quickguide.html)
and licensed under the terms of the **GPL-3.0-or-later** (see
[tools/zalsa/LICENSE](tools/zalsa/LICENSE)).
0707010000000A000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000001C00000000jack-example-tools-1/common0707010000000B000081A400000000000000000000000161E2F7EE0000ABAD000000000000000000000000000000000000002500000000jack-example-tools-1/common/memops.c/*
    Copyright (C) 2000 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#define _ISOC9X_SOURCE  1
#define _ISOC99_SOURCE  1

#define __USE_ISOC9X    1
#define __USE_ISOC99    1

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#ifdef __linux__
#include <endian.h>
#endif
#include "memops.h"

#if defined (__SSE2__) && !defined (__sun__)
#include <emmintrin.h>
#ifdef __SSE4_1__
#include <smmintrin.h>
#endif
#endif

#if defined (__ARM_NEON__) || defined (__ARM_NEON)
#include <arm_neon.h>
#endif

/* Notes about these *_SCALING values.

   the MAX_<N>BIT values are floating point. when multiplied by
   a full-scale normalized floating point sample value (-1.0..+1.0)
   they should give the maximum value representable with an integer
   sample type of N bits. Note that this is asymmetric. Sample ranges 
   for signed integer, 2's complement values are -(2^(N-1) to +(2^(N-1)-1)

   Complications
   -------------
   If we use +2^(N-1) for the scaling factors, we run into a problem:

   if we start with a normalized float value of -1.0, scaling
   to 24 bits would give -8388608 (-2^23), which is ideal.
   But with +1.0, we get +8388608, which is technically out of range.

   We never multiply a full range normalized value by this constant,
   but we could multiply it by a positive value that is close enough to +1.0
   to produce a value > +(2^(N-1)-1.

   There is no way around this paradox without wasting CPU cycles to determine
   which scaling factor to use (i.e. determine if its negative or not,
   use the right factor).

   So, for now (October 2008) we use 2^(N-1)-1 as the scaling factor.
*/

#define SAMPLE_32BIT_SCALING  2147483647.0
#define SAMPLE_24BIT_SCALING  8388607.0f
#define SAMPLE_16BIT_SCALING  32767.0f

/* these are just values to use if the floating point value was out of range
   
   advice from Fons Adriaensen: make the limits symmetrical
 */

#define SAMPLE_32BIT_MAX   2147483647
#define SAMPLE_32BIT_MIN   -2147483647
#define SAMPLE_32BIT_MAX_D  2147483647.0
#define SAMPLE_32BIT_MIN_D  -2147483647.0

#define SAMPLE_24BIT_MAX  8388607  
#define SAMPLE_24BIT_MIN  -8388607 
#define SAMPLE_24BIT_MAX_F  8388607.0f  
#define SAMPLE_24BIT_MIN_F  -8388607.0f 

#define SAMPLE_16BIT_MAX  32767
#define SAMPLE_16BIT_MIN  -32767
#define SAMPLE_16BIT_MAX_F  32767.0f
#define SAMPLE_16BIT_MIN_F  -32767.0f

/* these mark the outer edges of the range considered "within" range
   for a floating point sample value. values outside (and on the boundaries) 
   of this range will be clipped before conversion; values within this 
   range will be scaled to appropriate values for the target sample
   type.
*/

#define NORMALIZED_FLOAT_MIN -1.0f
#define NORMALIZED_FLOAT_MAX  1.0f

/* define this in case we end up on a platform that is missing
   the real lrintf functions
*/

#define f_round(f) lrintf(f)
#define d_round(f) lrint(f)

#define float_16(s, d)\
	if ((s) <= NORMALIZED_FLOAT_MIN) {\
		(d) = SAMPLE_16BIT_MIN;\
	} else if ((s) >= NORMALIZED_FLOAT_MAX) {\
		(d) = SAMPLE_16BIT_MAX;\
	} else {\
		(d) = f_round ((s) * SAMPLE_16BIT_SCALING);\
	}

/* call this when "s" has already been scaled (e.g. when dithering)
 */

#define float_16_scaled(s, d)\
        if ((s) <= SAMPLE_16BIT_MIN_F) {\
		(d) = SAMPLE_16BIT_MIN_F;\
	} else if ((s) >= SAMPLE_16BIT_MAX_F) {	\
		(d) = SAMPLE_16BIT_MAX;\
	} else {\
	        (d) = f_round ((s));\
	}

#define float_24u32(s, d) \
	if ((s) <= NORMALIZED_FLOAT_MIN) {\
		(d) = SAMPLE_24BIT_MIN << 8;\
	} else if ((s) >= NORMALIZED_FLOAT_MAX) {\
		(d) = SAMPLE_24BIT_MAX << 8;\
	} else {\
		(d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8;\
	}

#define float_24l32(s, d)                                              \
	if ((s) <= NORMALIZED_FLOAT_MIN) {\
		(d) = SAMPLE_24BIT_MIN;                                        \
	} else if ((s) >= NORMALIZED_FLOAT_MAX) {\
		(d) = SAMPLE_24BIT_MAX;                                        \
	} else {\
		(d) = f_round ((s) * SAMPLE_24BIT_SCALING);                    \
	}

#define float_32(s, d)												\
	do {															\
		double clipped = fmin(NORMALIZED_FLOAT_MAX,					\
				fmax((double)(s), NORMALIZED_FLOAT_MIN));			\
		double scaled = clipped * SAMPLE_32BIT_MAX_D;				\
		(d) = d_round(scaled);										\
	}																\
	while (0)

/* call this when "s" has already been scaled (e.g. when dithering)
 */

#define float_24u32_scaled(s, d)\
        if ((s) <= SAMPLE_24BIT_MIN_F) {\
		(d) = SAMPLE_24BIT_MIN << 8;\
	} else if ((s) >= SAMPLE_24BIT_MAX_F) {	\
		(d) = SAMPLE_24BIT_MAX << 8;		\
	} else {\
		(d) = f_round ((s)) << 8; \
	}

#define float_24(s, d) \
	if ((s) <= NORMALIZED_FLOAT_MIN) {\
		(d) = SAMPLE_24BIT_MIN;\
	} else if ((s) >= NORMALIZED_FLOAT_MAX) {\
		(d) = SAMPLE_24BIT_MAX;\
	} else {\
		(d) = f_round ((s) * SAMPLE_24BIT_SCALING);\
	}

/* call this when "s" has already been scaled (e.g. when dithering)
 */

#define float_24_scaled(s, d)\
        if ((s) <= SAMPLE_24BIT_MIN_F) {\
		(d) = SAMPLE_24BIT_MIN;\
	} else if ((s) >= SAMPLE_24BIT_MAX_F) {	\
		(d) = SAMPLE_24BIT_MAX;		\
	} else {\
		(d) = f_round ((s)); \
	}


#if defined (__SSE2__) && !defined (__sun__)

/* generates same as _mm_set_ps(1.f, 1.f, 1f., 1f) but faster  */
static inline __m128 gen_one(void)
{
    volatile __m128i x = { 0 }; /* shut up, GCC */
    __m128i ones = _mm_cmpeq_epi32(x, x);
    return (__m128)_mm_slli_epi32 (_mm_srli_epi32(ones, 25), 23);
}

static inline __m128 clip(__m128 s, __m128 min, __m128 max)
{
    return _mm_min_ps(max, _mm_max_ps(s, min));
}

static inline __m128d clip_double(__m128d s, __m128d min, __m128d max)
{
    return _mm_min_pd(max, _mm_max_pd(s, min));
}

static inline __m128i float_24_sse(__m128 s)
{
    const __m128 upper_bound = gen_one(); /* NORMALIZED_FLOAT_MAX */
    const __m128 lower_bound = _mm_sub_ps(_mm_setzero_ps(), upper_bound);

    __m128 clipped = clip(s, lower_bound, upper_bound);
    __m128 scaled = _mm_mul_ps(clipped, _mm_set1_ps(SAMPLE_24BIT_SCALING));
    return _mm_cvtps_epi32(scaled);
}
#endif


#if defined (__ARM_NEON__) || defined (__ARM_NEON)

static inline float32x4_t clip(float32x4_t s, float32x4_t min, float32x4_t max)
{
	return vminq_f32(max, vmaxq_f32(s, min));
}

static inline int32x4_t float_24_neon(float32x4_t s)
{
	const float32x4_t upper_bound = vdupq_n_f32(NORMALIZED_FLOAT_MAX);
	const float32x4_t lower_bound = vdupq_n_f32(NORMALIZED_FLOAT_MIN);

	float32x4_t clipped = clip(s, lower_bound, upper_bound);
	float32x4_t scaled = vmulq_f32(clipped, vdupq_n_f32(SAMPLE_24BIT_SCALING));
	return vcvtq_s32_f32(scaled);
}

static inline int16x4_t float_16_neon(float32x4_t s)
{
	const float32x4_t upper_bound = vdupq_n_f32(NORMALIZED_FLOAT_MAX);
	const float32x4_t lower_bound = vdupq_n_f32(NORMALIZED_FLOAT_MIN);

	float32x4_t clipped = clip(s, lower_bound, upper_bound);
	float32x4_t scaled = vmulq_f32(clipped, vdupq_n_f32(SAMPLE_16BIT_SCALING));
	return vmovn_s32(vcvtq_s32_f32(scaled));
}
#endif

/* Linear Congruential noise generator. From the music-dsp list
 * less random than rand(), but good enough and 10x faster 
 */
static unsigned int seed = 22222;

static inline unsigned int fast_rand() {
	seed = (seed * 196314165) + 907633515;
	return seed;
}

/* functions for native float sample data */

void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) {
	while (nsamples--) {
		*dst = *((float *) src);
		dst++;
		src += src_skip;
	}
}

void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) {
	while (nsamples--) {
		*((float *) dst) = *src;
		dst += dst_skip;
		src++;
	}
}

/* NOTES on function naming:

   foo_bar_d<TYPE>_s<TYPE>

   the "d<TYPE>" component defines the destination type for the operation
   the "s<TYPE>" component defines the source type for the operation

   TYPE can be one of:
   
   S      - sample is a jack_default_audio_sample_t, currently (October 2008) a 32 bit floating point value
   Ss     - like S but reverse endian from the host CPU
   32     - sample is a signed 32 bit integer value
   32u24  - sample is a signed 32 bit integer value, but data is in upper 24 bits only
   32u24s - like 32u24 but reverse endian from the host CPU
   32l24  - sample is a signed 32 bit integer value, but data is in lower 24 bits only
   32l24s - like 32l24 but reverse endian from the host CPU
   24     - sample is a signed 24 bit integer value
   24s    - like 24 but reverse endian from the host CPU
   16     - sample is a signed 16 bit integer value
   16s    - like 16 but reverse endian from the host CPU

   For obvious reasons, the reverse endian versions only show as source types.

   This covers all known sample formats at 16 bits or larger.
*/   

/* functions for native integer sample data */

void sample_move_d32_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
	while (nsamples--) {
		int32_t z;
		float_32(*src, z);
#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(z>>24);
		dst[1]=(char)(z>>16);
		dst[2]=(char)(z>>8);
		dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(z);
		dst[1]=(char)(z>>8);
		dst[2]=(char)(z>>16);
		dst[3]=(char)(z>>24);
#endif
		dst += dst_skip;
		src++;
	}
}

void sample_move_d32_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
	while (nsamples--) {
		float_32(*src, *(int32_t *)dst);
		dst += dst_skip;
		src++;
	}
}

void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);
		int32x4_t shifted = vshlq_n_s32(converted, 8);
		shifted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(shifted)));

		switch(dst_skip) {
			case 4:
				vst1q_s32((int32_t*)dst, shifted);
				break;
			default:
				vst1q_lane_s32((int32_t*)(dst),            shifted, 0);
				vst1q_lane_s32((int32_t*)(dst+dst_skip),   shifted, 1);
				vst1q_lane_s32((int32_t*)(dst+2*dst_skip), shifted, 2);
                vst1q_lane_s32((int32_t*)(dst+3*dst_skip), shifted, 3);
				break;
		}
		dst += 4*dst_skip;
		src+= 4;
	}
#endif

	int32_t z;

	while (nsamples--) {

		float_24u32 (*src, z);

#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(z>>24);
		dst[1]=(char)(z>>16);
		dst[2]=(char)(z>>8);
		dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(z);
		dst[1]=(char)(z>>8);
		dst[2]=(char)(z>>16);
		dst[3]=(char)(z>>24);
#endif
		dst += dst_skip;
		src++;
	}
}	

void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__SSE2__) && !defined (__sun__)
	__m128 int_max = _mm_set1_ps(SAMPLE_24BIT_MAX_F);
	__m128 int_min = _mm_sub_ps(_mm_setzero_ps(), int_max);
	__m128 factor = int_max;

	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		__m128 in = _mm_load_ps(src);
		__m128 scaled = _mm_mul_ps(in, factor);
		__m128 clipped = clip(scaled, int_min, int_max);

		__m128i y = _mm_cvttps_epi32(clipped);
		__m128i shifted = _mm_slli_epi32(y, 8);

#ifdef __SSE4_1__
		*(int32_t*)dst              = _mm_extract_epi32(shifted, 0);
		*(int32_t*)(dst+dst_skip)   = _mm_extract_epi32(shifted, 1);
		*(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2);
		*(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3);
#else
		__m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1));
		__m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2));
		__m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3));

		_mm_store_ss((float*)dst, (__m128)shifted);

		_mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1);
		_mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2);
		_mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3);
#endif
		dst += 4*dst_skip;

		src+= 4;
	}

	while (nsamples--) {
		__m128 in = _mm_load_ss(src);
		__m128 scaled = _mm_mul_ss(in, factor);
		__m128 clipped = _mm_min_ss(int_max, _mm_max_ss(scaled, int_min));

		int y = _mm_cvttss_si32(clipped);
		*((int *) dst) = y<<8;

		dst += dst_skip;
		src++;
	}

#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);
		int32x4_t shifted = vshlq_n_s32(converted, 8);

		switch(dst_skip) {
			case 4:
				vst1q_s32((int32_t*)dst, shifted);
				break;
			default:
				vst1q_lane_s32((int32_t*)(dst),            shifted, 0);
				vst1q_lane_s32((int32_t*)(dst+dst_skip),   shifted, 1);
				vst1q_lane_s32((int32_t*)(dst+2*dst_skip), shifted, 2);
                vst1q_lane_s32((int32_t*)(dst+3*dst_skip), shifted, 3);
				break;
		}
		dst += 4*dst_skip;

		src+= 4;
	}
#endif

#if !defined (__SSE2__)
	while (nsamples--) {
		float_24u32 (*src, *((int32_t*) dst));
		dst += dst_skip;
		src++;
	}
#endif
}	

void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING);
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		int32x4_t src128;
		switch(src_skip)
		{
			case 4:
				src128 = vld1q_s32((int32_t*)src);
				break;
			case 8:
				src128 = vld2q_s32((int32_t*)src).val[0];
				break;
			default:
				src128 = vld1q_lane_s32((int32_t*)src,              src128, 0);
				src128 = vld1q_lane_s32((int32_t*)(src+src_skip),   src128, 1);
				src128 = vld1q_lane_s32((int32_t*)(src+2*src_skip), src128, 2);
				src128 = vld1q_lane_s32((int32_t*)(src+3*src_skip), src128, 3);
				break;
		}
		src128 = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(src128)));
		int32x4_t shifted = vshrq_n_s32(src128, 8);
		float32x4_t as_float = vcvtq_f32_s32(shifted);
		float32x4_t divided = vmulq_f32(as_float, factor);
		vst1q_f32(dst, divided);

		src += 4*src_skip;
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */

	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING;

	while (nsamples--) {
		int x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
		x = (unsigned char)(src[0]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[3]);
#elif __BYTE_ORDER == __BIG_ENDIAN
		x = (unsigned char)(src[3]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[0]);
#endif
		*dst = (x >> 8) * scaling;
		dst++;
		src += src_skip;
	}
}	

void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
#if defined (__SSE2__) && !defined (__sun__)
	unsigned long unrolled = nsamples / 4;
	static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING;
	__m128 factor = _mm_set1_ps(inv_sample_max_24bit);
	while (unrolled--)
	{
		int i1 = *((int *) src);
		src+= src_skip;
		int i2 = *((int *) src);
		src+= src_skip;
		int i3 = *((int *) src);
		src+= src_skip;
		int i4 = *((int *) src);
		src+= src_skip;

		__m128i src = _mm_set_epi32(i4, i3, i2, i1);
		__m128i shifted = _mm_srai_epi32(src, 8);

		__m128 as_float = _mm_cvtepi32_ps(shifted);
		__m128 divided = _mm_mul_ps(as_float, factor);

		_mm_storeu_ps(dst, divided);

		dst += 4;
	}
	nsamples = nsamples & 3;
#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING);
	while (unrolled--) {
		int32x4_t src128;
		switch(src_skip) {
			case 4:
				src128 = vld1q_s32((int32_t*)src);
				break;
			case 8:
				src128 = vld2q_s32((int32_t*)src).val[0];
				break;
			default:
				src128 = vld1q_lane_s32((int32_t*)src,              src128, 0);
				src128 = vld1q_lane_s32((int32_t*)(src+src_skip),   src128, 1);
				src128 = vld1q_lane_s32((int32_t*)(src+2*src_skip), src128, 2);
				src128 = vld1q_lane_s32((int32_t*)(src+3*src_skip), src128, 3);
				break;
		}
		int32x4_t shifted = vshrq_n_s32(src128, 8);
		float32x4_t as_float = vcvtq_f32_s32(shifted);
		float32x4_t divided = vmulq_f32(as_float, factor);
		vst1q_f32(dst, divided);

		src += 4*src_skip;
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */

	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING;
	while (nsamples--) {
		*dst = (*((int *) src) >> 8) * scaling;
		dst++;
		src += src_skip;
	}
}	

void sample_move_d32l24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);
		converted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(converted)));

		switch(dst_skip) {
			case 4:
				vst1q_s32((int32_t*)dst, converted);
				break;
			default:
				vst1q_lane_s32((int32_t*)(dst),            converted, 0);
				vst1q_lane_s32((int32_t*)(dst+dst_skip),   converted, 1);
				vst1q_lane_s32((int32_t*)(dst+2*dst_skip), converted, 2);
                vst1q_lane_s32((int32_t*)(dst+3*dst_skip), converted, 3);
				break;
		}
		dst += 4*dst_skip;
		src+= 4;
	}
#endif

	int32_t z;

	while (nsamples--) {

		float_24l32 (*src, z);

#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(z>>24);
		dst[1]=(char)(z>>16);
		dst[2]=(char)(z>>8);
		dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(z);
		dst[1]=(char)(z>>8);
		dst[2]=(char)(z>>16);
		dst[3]=(char)(z>>24);
#endif
		dst += dst_skip;
		src++;
	}
}	

void sample_move_d32l24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__SSE2__) && !defined (__sun__)
	__m128 int_max = _mm_set1_ps(SAMPLE_24BIT_MAX_F);
	__m128 int_min = _mm_sub_ps(_mm_setzero_ps(), int_max);
	__m128 factor = int_max;

	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		__m128 in = _mm_load_ps(src);
		__m128 scaled = _mm_mul_ps(in, factor);
		__m128 clipped = clip(scaled, int_min, int_max);

		__m128i shifted = _mm_cvttps_epi32(clipped);

#ifdef __SSE4_1__
		*(int32_t*)dst              = _mm_extract_epi32(shifted, 0);
		*(int32_t*)(dst+dst_skip)   = _mm_extract_epi32(shifted, 1);
		*(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2);
		*(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3);
#else
		__m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1));
		__m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2));
		__m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3));

		_mm_store_ss((float*)dst, (__m128)shifted);

		_mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1);
		_mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2);
		_mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3);
#endif
		dst += 4*dst_skip;

		src+= 4;
	}

	while (nsamples--) {
		__m128 in = _mm_load_ss(src);
		__m128 scaled = _mm_mul_ss(in, factor);
		__m128 clipped = _mm_min_ss(int_max, _mm_max_ss(scaled, int_min));

		int y = _mm_cvttss_si32(clipped);
		*((int *) dst) = y<<8;

		dst += dst_skip;
		src++;
	}
#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);

		switch(dst_skip) {
			case 4:
				vst1q_s32((int32_t*)dst, converted);
				break;
			default:
				vst1q_lane_s32((int32_t*)(dst),            converted, 0);
				vst1q_lane_s32((int32_t*)(dst+dst_skip),   converted, 1);
				vst1q_lane_s32((int32_t*)(dst+2*dst_skip), converted, 2);
                vst1q_lane_s32((int32_t*)(dst+3*dst_skip), converted, 3);
				break;
		}
		dst += 4*dst_skip;

		src+= 4;
	}
#endif

#if !defined (__SSE2__)
	while (nsamples--) {
		float_24l32 (*src, *((int32_t*) dst));
		dst += dst_skip;
		src++;
	}
#endif
}	

void sample_move_dS_s32s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_32BIT_SCALING;
	while (nsamples--) {
		int32_t x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
		x = (unsigned char)(src[0]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[3]);
#elif __BYTE_ORDER == __BIG_ENDIAN
		x = (unsigned char)(src[3]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[0]);
#endif
		double extended = x * scaling;
		*dst = (float)extended;
		dst++;
		src += src_skip;
	}
}

void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING);
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		uint32x4_t src128;
		switch(src_skip)
		{
			case 4:
				src128 = vld1q_u32((uint32_t*)src);
				break;
			case 8:
				src128 = vld2q_u32((uint32_t*)src).val[0];
				break;
			default:
				src128 = vld1q_lane_u32((uint32_t*)src,              src128, 0);
				src128 = vld1q_lane_u32((uint32_t*)(src+src_skip),   src128, 1);
				src128 = vld1q_lane_u32((uint32_t*)(src+2*src_skip), src128, 2);
				src128 = vld1q_lane_u32((uint32_t*)(src+3*src_skip), src128, 3);
				break;
		}
		src128 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(src128)));
		uint32x4_t toupper = vshlq_n_u32(src128, 8);
		int32x4_t shifted = vshrq_n_s32((int32x4_t)toupper, 8);
		float32x4_t as_float = vcvtq_f32_s32(shifted);
		float32x4_t divided = vmulq_f32(as_float, factor);
		vst1q_f32(dst, divided);

		src += 4*src_skip;
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */

	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING;

	while (nsamples--) {
		int32_t x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
		x = (unsigned char)(src[0]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[3]);
#elif __BYTE_ORDER == __BIG_ENDIAN
		x = (unsigned char)(src[3]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[0]);
#endif
		*dst = (x >> 0) * scaling;
		dst++;
		src += src_skip;
	}
}	

void sample_move_dS_s32 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
	const double scaling = 1.0 / SAMPLE_32BIT_SCALING;
	while (nsamples--) {
		int32_t val=(*((int32_t*)src));
		double extended = val * scaling;
		*dst = (float)extended;
		dst++;
		src += src_skip;
	}
}

void sample_move_dS_s32l24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
#if defined (__SSE2__) && !defined (__sun__)
	unsigned long unrolled = nsamples / 4;
	static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING;
	__m128 factor = _mm_set1_ps(inv_sample_max_24bit);
	while (unrolled--)
	{
		int i1 = *((int *) src);
		src+= src_skip;
		int i2 = *((int *) src);
		src+= src_skip;
		int i3 = *((int *) src);
		src+= src_skip;
		int i4 = *((int *) src);
		src+= src_skip;

		__m128i shifted = _mm_set_epi32(i4, i3, i2, i1);

		__m128 as_float = _mm_cvtepi32_ps(shifted);
		__m128 divided = _mm_mul_ps(as_float, factor);

		_mm_storeu_ps(dst, divided);

		dst += 4;
	}
	nsamples = nsamples & 3;
#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING);
	while (unrolled--) {
		uint32x4_t src128;
		switch(src_skip) {
			case 4:
				src128 = vld1q_u32((uint32_t*)src);
				break;
			case 8:
				src128 = vld2q_u32((uint32_t*)src).val[0];
				break;
			default:
				src128 = vld1q_lane_u32((uint32_t*)src,              src128, 0);
				src128 = vld1q_lane_u32((uint32_t*)(src+src_skip),   src128, 1);
				src128 = vld1q_lane_u32((uint32_t*)(src+2*src_skip), src128, 2);
				src128 = vld1q_lane_u32((uint32_t*)(src+3*src_skip), src128, 3);
				break;
		}
		// Sign extension by moving to upper as unsigned, then down
		uint32x4_t toupper = vshlq_n_u32(src128, 8);
		int32x4_t shifted = vshrq_n_s32((int32x4_t)toupper, 8);
		float32x4_t as_float = vcvtq_f32_s32(shifted);
		float32x4_t divided = vmulq_f32(as_float, factor);
		vst1q_f32(dst, divided);

		src += 4*src_skip;
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */

	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING;
	while (nsamples--) {
		uint32_t val=(*((uint32_t*)src));
		if (val & 0x800000u) val|=0xFF000000u;
		*dst = (*((int32_t *) &val)) * scaling;
		dst++;
		src += src_skip;
	}
}	

void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		int i;
		int32_t z[4];
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);
		converted = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(converted)));
		vst1q_s32(z, converted);

		for (i = 0; i != 4; ++i) {
			memcpy (dst, ((char*)(z+i))+1, 3);
			dst += dst_skip;
		}
		src += 4;
	}
	nsamples = nsamples & 3;
#endif

	int32_t z;

	while (nsamples--) {
		float_24 (*src, z);
#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(z>>16);
		dst[1]=(char)(z>>8);
		dst[2]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(z);
		dst[1]=(char)(z>>8);
		dst[2]=(char)(z>>16);
#endif
		dst += dst_skip;
		src++;
	}
}	

void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
#if defined (__SSE2__) && !defined (__sun__)
	_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
	while (nsamples >= 4) {
		int i;
		int32_t z[4];
		__m128 samples = _mm_loadu_ps(src);
		__m128i converted = float_24_sse(samples);

#ifdef __SSE4_1__
		z[0] = _mm_extract_epi32(converted, 0);
		z[1] = _mm_extract_epi32(converted, 1);
		z[2] = _mm_extract_epi32(converted, 2);
		z[3] = _mm_extract_epi32(converted, 3);
#else
		__m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1));
		__m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2));
		__m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3));

		_mm_store_ss((float*)z, (__m128)converted);
		_mm_store_ss((float*)z+1, (__m128)shuffled1);
		_mm_store_ss((float*)z+2, (__m128)shuffled2);
		_mm_store_ss((float*)z+3, (__m128)shuffled3);
#endif

		for (i = 0; i != 4; ++i) {
			memcpy (dst, z+i, 3);
			dst += dst_skip;
		}

		nsamples -= 4;
		src += 4;
	}
#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		int i;
		int32_t z[4];
		float32x4_t samples = vld1q_f32(src);
		int32x4_t converted = float_24_neon(samples);
		vst1q_s32(z, converted);

		for (i = 0; i != 4; ++i) {
			memcpy (dst, z+i, 3);
			dst += dst_skip;
		}
		src += 4;
	}
	nsamples = nsamples & 3;
#endif

    int32_t z;

	while (nsamples--) {
		float_24 (*src, z);
#if __BYTE_ORDER == __LITTLE_ENDIAN
		memcpy (dst, &z, 3);
#elif __BYTE_ORDER == __BIG_ENDIAN
		memcpy (dst, (char *)&z + 1, 3);
#endif
		dst += dst_skip;
		src++;
	}
}

void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING;

#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	// we shift 8 to the right by dividing by 256.0 -> no sign extra handling
	const float32x4_t vscaling = vdupq_n_f32(scaling/256.0);
	int32_t x[4];
	memset(x, 0, sizeof(x));
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
#if __BYTE_ORDER == __BIG_ENDIAN	 /* ARM big endian?? */
		// right aligned / inverse sequence below -> *256
		memcpy(((char*)&x[0])+1, src, 3);
		memcpy(((char*)&x[1])+1, src+src_skip, 3);
		memcpy(((char*)&x[2])+1, src+2*src_skip, 3);
		memcpy(((char*)&x[3])+1, src+3*src_skip, 3);
#else
		memcpy(&x[0], src, 3);
		memcpy(&x[1], src+src_skip, 3);
		memcpy(&x[2], src+2*src_skip, 3);
		memcpy(&x[3], src+3*src_skip, 3);
#endif
		src += 4 * src_skip;

		int32x4_t source = vld1q_s32(x);
		source = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(source)));
		float32x4_t converted = vcvtq_f32_s32(source);
		float32x4_t scaled = vmulq_f32(converted, vscaling);
		vst1q_f32(dst, scaled);
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */

	while (nsamples--) {
		int x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
		x = (unsigned char)(src[0]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[2]);
		/* correct sign bit and the rest of the top byte */
		if (src[0] & 0x80) {
			x |= 0xff << 24;
		}
#elif __BYTE_ORDER == __BIG_ENDIAN
		x = (unsigned char)(src[2]);
		x <<= 8;
		x |= (unsigned char)(src[1]);
		x <<= 8;
		x |= (unsigned char)(src[0]);
		/* correct sign bit and the rest of the top byte */
		if (src[2] & 0x80) {
			x |= 0xff << 24;
		}
#endif
		*dst = x * scaling;
		dst++;
		src += src_skip;
	}
}

void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
	const jack_default_audio_sample_t scaling = 1.f/SAMPLE_24BIT_SCALING;

#if defined (__SSE2__) && !defined (__sun__)
	const __m128 scaling_block = _mm_set_ps1(scaling);
	while (nsamples >= 4) {
		int x0, x1, x2, x3;

		memcpy((char*)&x0 + 1, src, 3);
		memcpy((char*)&x1 + 1, src+src_skip, 3);
		memcpy((char*)&x2 + 1, src+2*src_skip, 3);
		memcpy((char*)&x3 + 1, src+3*src_skip, 3);
		src += 4 * src_skip;

		const __m128i block_i = _mm_set_epi32(x3, x2, x1, x0);
		const __m128i shifted = _mm_srai_epi32(block_i, 8);
		const __m128 converted = _mm_cvtepi32_ps (shifted);
		const __m128 scaled = _mm_mul_ps(converted, scaling_block);
		_mm_storeu_ps(dst, scaled);
		dst += 4;
		nsamples -= 4;
	}
#elif defined (__ARM_NEON__) || defined (__ARM_NEON)
	// we shift 8 to the right by dividing by 256.0 -> no sign extra handling
	const float32x4_t vscaling = vdupq_n_f32(scaling/256.0);
	int32_t x[4];
	memset(x, 0, sizeof(x));
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
#if __BYTE_ORDER == __BIG_ENDIAN	/* ARM big endian?? */
		// left aligned -> *256
		memcpy(&x[0], src, 3);
		memcpy(&x[1], src+src_skip, 3);
		memcpy(&x[2], src+2*src_skip, 3);
		memcpy(&x[3], src+3*src_skip, 3);
#else
		memcpy(((char*)&x[0])+1, src, 3);
		memcpy(((char*)&x[1])+1, src+src_skip, 3);
		memcpy(((char*)&x[2])+1, src+2*src_skip, 3);
		memcpy(((char*)&x[3])+1, src+3*src_skip, 3);
#endif
		src += 4 * src_skip;

		int32x4_t source = vld1q_s32(x);
		float32x4_t converted = vcvtq_f32_s32(source);
		float32x4_t scaled = vmulq_f32(converted, vscaling);
		vst1q_f32(dst, scaled);
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	while (nsamples--) {
		int x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
		memcpy((char*)&x + 1, src, 3);
#elif __BYTE_ORDER == __BIG_ENDIAN
		memcpy(&x, src, 3);
#endif
		x >>= 8;
		*dst = x * scaling;
		dst++;
		src += src_skip;
	}
}


void sample_move_d16_sSs (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int16x4_t converted = float_16_neon(samples);
		converted = vreinterpret_s16_u8(vrev16_u8(vreinterpret_u8_s16(converted)));

		switch(dst_skip) {
			case 2:
				vst1_s16((int16_t*)dst, converted);
				break;
			default:
				vst1_lane_s16((int16_t*)(dst),            converted, 0);
				vst1_lane_s16((int16_t*)(dst+dst_skip),   converted, 1);
				vst1_lane_s16((int16_t*)(dst+2*dst_skip), converted, 2);
				vst1_lane_s16((int16_t*)(dst+3*dst_skip), converted, 3);
				break;
		}
		dst += 4*dst_skip;
		src+= 4;
	}
#endif
	int16_t tmp;

	while (nsamples--) {
		// float_16 (*src, tmp);

		if (*src <= NORMALIZED_FLOAT_MIN) {
			tmp = SAMPLE_16BIT_MIN;
		} else if (*src >= NORMALIZED_FLOAT_MAX) {
			tmp = SAMPLE_16BIT_MAX;
		} else {
			tmp = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING);
		}

#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(tmp>>8);
		dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(tmp);
		dst[1]=(char)(tmp>>8);
#endif
		dst += dst_skip;
		src++;
	}
}

void sample_move_d16_sS (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	unsigned long unrolled = nsamples / 4;
	nsamples = nsamples & 3;

	while (unrolled--) {
		float32x4_t samples = vld1q_f32(src);
		int16x4_t converted = float_16_neon(samples);

		switch(dst_skip) {
			case 2:
				vst1_s16((int16_t*)dst, converted);
				break;
			default:
				vst1_lane_s16((int16_t*)(dst),            converted, 0);
				vst1_lane_s16((int16_t*)(dst+dst_skip),   converted, 1);
				vst1_lane_s16((int16_t*)(dst+2*dst_skip), converted, 2);
				vst1_lane_s16((int16_t*)(dst+3*dst_skip), converted, 3);
				break;
		}
		dst += 4*dst_skip;
		src+= 4;
	}
#endif
	while (nsamples--) {
		float_16 (*src, *((int16_t*) dst));
		dst += dst_skip;
		src++;
	}
}

void sample_move_dither_rect_d16_sSs (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t val;
	int16_t      tmp;

	while (nsamples--) {
		val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float) UINT_MAX - 0.5f;
		float_16_scaled (val, tmp);
#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(tmp>>8);
		dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(tmp);
		dst[1]=(char)(tmp>>8);
#endif
		dst += dst_skip;
		src++;
	}
}

void sample_move_dither_rect_d16_sS (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t val;

	while (nsamples--) {
		val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float)UINT_MAX - 0.5f;
		float_16_scaled (val, *((int16_t*) dst));
		dst += dst_skip;
		src++;
	}
}

void sample_move_dither_tri_d16_sSs (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t val;
	int16_t      tmp;

	while (nsamples--) {
		val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f;
		float_16_scaled (val, tmp);

#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(tmp>>8);
		dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(tmp);
		dst[1]=(char)(tmp>>8);
#endif
		dst += dst_skip;
		src++;
	}
}

void sample_move_dither_tri_d16_sS (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t val;

	while (nsamples--) {
		val = (*src * SAMPLE_16BIT_SCALING) + ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f;
		float_16_scaled (val, *((int16_t*) dst));
		dst += dst_skip;
		src++;
	}
}

void sample_move_dither_shaped_d16_sSs (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t     x;
	jack_default_audio_sample_t     xe; /* the innput sample - filtered error */
	jack_default_audio_sample_t     xp; /* x' */
	float        r;
	float        rm1 = state->rm1;
	unsigned int idx = state->idx;
	int16_t      tmp;

	while (nsamples--) {
		x = *src * SAMPLE_16BIT_SCALING;
		r = ((float)fast_rand() + (float)fast_rand())  / (float)UINT_MAX - 1.0f;
		/* Filter the error with Lipshitz's minimally audible FIR:
		   [2.033 -2.165 1.959 -1.590 0.6149] */
		xe = x
		     - state->e[idx] * 2.033f
		     + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
		     - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
		     + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
		     - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
		xp = xe + r - rm1;
		rm1 = r;

		float_16_scaled (xp, tmp);

		/* Intrinsic z^-1 delay */
		idx = (idx + 1) & DITHER_BUF_MASK;
		state->e[idx] = xp - xe;

#if __BYTE_ORDER == __LITTLE_ENDIAN
		dst[0]=(char)(tmp>>8);
		dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
		dst[0]=(char)(tmp);
		dst[1]=(char)(tmp>>8);
#endif
		dst += dst_skip;
		src++;
	}
	state->rm1 = rm1;
	state->idx = idx;
}

void sample_move_dither_shaped_d16_sS (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)	
{
	jack_default_audio_sample_t     x;
	jack_default_audio_sample_t     xe; /* the innput sample - filtered error */
	jack_default_audio_sample_t     xp; /* x' */
	float        r;
	float        rm1 = state->rm1;
	unsigned int idx = state->idx;

	while (nsamples--) {
		x = *src * SAMPLE_16BIT_SCALING;
		r = ((float)fast_rand() + (float)fast_rand()) / (float)UINT_MAX - 1.0f;
		/* Filter the error with Lipshitz's minimally audible FIR:
		   [2.033 -2.165 1.959 -1.590 0.6149] */
		xe = x
		     - state->e[idx] * 2.033f
		     + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
		     - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
		     + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
		     - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
		xp = xe + r - rm1;
		rm1 = r;

		float_16_scaled (xp, *((int16_t*) dst));

		/* Intrinsic z^-1 delay */
		idx = (idx + 1) & DITHER_BUF_MASK;
		state->e[idx] = *((int16_t*) dst) - xe;

		dst += dst_skip;
		src++;
	}
	state->rm1 = rm1;
	state->idx = idx;
}

void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) 	
{
	short z;
	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING;
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	const float32x4_t vscaling = vdupq_n_f32(scaling);
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		int16x4_t source16x4;
		switch(src_skip) {
			case 2:
				source16x4 = vld1_s16((int16_t*)src);
				break;
			case 4:
				source16x4 = vld2_s16((int16_t*)src).val[0];
				break;
			default:
				source16x4 = vld1_lane_s16((int16_t*)src,              source16x4, 0);
				source16x4 = vld1_lane_s16((int16_t*)(src+src_skip),   source16x4, 1);
				source16x4 = vld1_lane_s16((int16_t*)(src+2*src_skip), source16x4, 2);
				source16x4 = vld1_lane_s16((int16_t*)(src+3*src_skip), source16x4, 3);
				break;
		}
		source16x4 = vreinterpret_s16_u8(vrev16_u8(vreinterpret_u8_s16(source16x4)));
		int32x4_t source32x4 = vmovl_s16(source16x4);
		src += 4 * src_skip;

		float32x4_t converted = vcvtq_f32_s32(source32x4);
		float32x4_t scaled = vmulq_f32(converted, vscaling);
		vst1q_f32(dst, scaled);
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	/* ALERT: signed sign-extension portability !!! */
	while (nsamples--) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
		z = (unsigned char)(src[0]);
		z <<= 8;
		z |= (unsigned char)(src[1]);
#elif __BYTE_ORDER == __BIG_ENDIAN
		z = (unsigned char)(src[1]);
		z <<= 8;
		z |= (unsigned char)(src[0]);
#endif
		*dst = z * scaling;
		dst++;
		src += src_skip;
	}
}	

void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) 
{
	/* ALERT: signed sign-extension portability !!! */
	const jack_default_audio_sample_t scaling = 1.0/SAMPLE_16BIT_SCALING;
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
	const float32x4_t vscaling = vdupq_n_f32(scaling);
	unsigned long unrolled = nsamples / 4;
	while (unrolled--) {
		int16x4_t source16x4;
		switch(src_skip) {
			case 2:
				source16x4 = vld1_s16((int16_t*)src);
				break;
			case 4:
				source16x4 = vld2_s16((int16_t*)src).val[0];
				break;
			default:
				source16x4 = vld1_lane_s16((int16_t*)src,              source16x4, 0);
				source16x4 = vld1_lane_s16((int16_t*)(src+src_skip),   source16x4, 1);
				source16x4 = vld1_lane_s16((int16_t*)(src+2*src_skip), source16x4, 2);
				source16x4 = vld1_lane_s16((int16_t*)(src+3*src_skip), source16x4, 3);
				break;
		}
		int32x4_t source32x4 = vmovl_s16(source16x4);
		src += 4 * src_skip;

		float32x4_t converted = vcvtq_f32_s32(source32x4);
		float32x4_t scaled = vmulq_f32(converted, vscaling);
		vst1q_f32(dst, scaled);
		dst += 4;
	}
	nsamples = nsamples & 3;
#endif

	while (nsamples--) {
		*dst = (*((short *) src)) * scaling;
		dst++;
		src += src_skip;
	}
}	

void memset_interleave (char *dst, char val, unsigned long bytes, 
			unsigned long unit_bytes, 
			unsigned long skip_bytes) 
{
	switch (unit_bytes) {
	case 1:
		while (bytes--) {
			*dst = val;
			dst += skip_bytes;
		}
		break;
	case 2:
		while (bytes) {
			*((short *) dst) = (short) val;
			dst += skip_bytes;
			bytes -= 2;
		}
		break;
	case 4:		    
		while (bytes) {
			*((int *) dst) = (int) val;
			dst += skip_bytes;
			bytes -= 4;
		}
		break;
	default:
		while (bytes) {
			memset(dst, val, unit_bytes);
			dst += skip_bytes;
			bytes -= unit_bytes;
		}
		break;
	}
}

/* COPY FUNCTIONS: used to move data from an input channel to an
   output channel. Note that we assume that the skip distance
   is the same for both channels. This is completely fine
   unless the input and output were on different audio interfaces that
   were interleaved differently. We don't try to handle that.
*/

void 
memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar)
{
	memcpy (dst, src, src_bytes);
}

void 
memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes,
			   unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
	while (src_bytes) {
		*((short *) dst) = *((short *) src);
		dst += dst_skip_bytes;
		src += src_skip_bytes;
		src_bytes -= 2;
	}
}

void 
memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes,
			   unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
	while (src_bytes) {
		memcpy(dst, src, 3);
		dst += dst_skip_bytes;
		src += src_skip_bytes;
		src_bytes -= 3;
	}
}

void 
memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes,
			   unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
	while (src_bytes) {
		*((int *) dst) = *((int *) src);
		dst += dst_skip_bytes;
		src += src_skip_bytes;
		src_bytes -= 4;
	}
}
0707010000000C000081A400000000000000000000000161E2F7EE0000249B000000000000000000000000000000000000002500000000jack-example-tools-1/common/memops.h/*
    Copyright (C) 1999-2000 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __jack_memops_h__
#define __jack_memops_h__

#include <jack/types.h>

#ifdef __cplusplus
extern "C"
{
#endif

#ifdef sun
#define __inline__
#endif

typedef	enum  {
	None,
	Rectangular,
	Triangular,
	Shaped
} DitherAlgorithm;

#define DITHER_BUF_SIZE 8
#define DITHER_BUF_MASK 7

typedef struct {
    unsigned int depth;
    float rm1;
    unsigned int idx;
    float e[DITHER_BUF_SIZE];
} dither_state_t;

/* float functions */
void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip);
void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

/* integer functions */
void sample_move_d32_sSs             (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32_sS              (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32u24_sSs          (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32u24_sS           (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32l24_sSs          (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32l24_sS           (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d24_sSs             (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d24_sS              (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d16_sSs             (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d16_sS              (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

void sample_move_dither_rect_d32u24_sSs   (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d32u24_sS    (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d32u24_sSs    (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d32u24_sS     (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d32u24_sS  (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d24_sSs      (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d24_sS       (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d24_sSs       (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d24_sS        (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d24_sSs    (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d24_sS     (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d16_sSs      (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d16_sS       (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d16_sSs       (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d16_sS        (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d16_sSs    (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d16_sS     (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

void sample_move_dS_s32s             (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32              (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32u24s          (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32u24           (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32l24s          (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32l24           (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s24s             (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s24              (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s16s             (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s16              (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);

void sample_merge_d16_sS             (char *dst,  jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_merge_d32u24_sS          (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

static __inline__ void
sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)
{
	while (cnt--) {
		*dst += *src;
		dst++;
		src++;
	}
}

static __inline__ void
sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)
{
	memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t));
}

void memset_interleave               (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes);
void memcpy_fake                     (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);

void memcpy_interleave_d16_s16       (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d24_s24       (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d32_s32       (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_d16_s16            (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);
void merge_memcpy_d32_s32            (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);

#ifdef __cplusplus
}
#endif

#endif /* __jack_memops_h__ */
0707010000000D000081A400000000000000000000000161E2F7EE0000A9DE000000000000000000000000000000000000002D00000000jack-example-tools-1/common/netjack_packet.c
/*
 * NetJack - Packet Handling functions
 *
 * used by the driver and the jacknet_client
 *
 * Copyright (C) 2019 Karl Linden <karl.j.linden@gmail.com>
 * Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org>
 * Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
 * Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $
 *
 */

#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#ifdef __APPLE__
#define _DARWIN_C_SOURCE
#endif

#if HAVE_PPOLL
#define _GNU_SOURCE
#endif

#include <alloca.h>
#include <math.h>
#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>

#include <jack/types.h>

#include <sys/types.h>

#ifdef WIN32
#include <winsock2.h>
#include <malloc.h>
#define socklen_t int
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>
#endif

#include <errno.h>
#include <signal.h>

#include <samplerate.h>

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include "netjack_packet.h"
// TODO: we explicitly do not include JackError.h here, as that includes half of jack2 as well
// #include "JackError.h"

#ifdef NO_JACK_ERROR
#define jack_error printf
#endif

int fraggo = 0;

void
packet_header_hton (jacknet_packet_header *pkthdr)
{
    pkthdr->capture_channels_audio = htonl(pkthdr->capture_channels_audio);
    pkthdr->playback_channels_audio = htonl(pkthdr->playback_channels_audio);
    pkthdr->capture_channels_midi = htonl(pkthdr->capture_channels_midi);
    pkthdr->playback_channels_midi = htonl(pkthdr->playback_channels_midi);
    pkthdr->period_size = htonl(pkthdr->period_size);
    pkthdr->sample_rate = htonl(pkthdr->sample_rate);
    pkthdr->sync_state = htonl(pkthdr->sync_state);
    pkthdr->transport_frame = htonl(pkthdr->transport_frame);
    pkthdr->transport_state = htonl(pkthdr->transport_state);
    pkthdr->framecnt = htonl(pkthdr->framecnt);
    pkthdr->latency = htonl(pkthdr->latency);
    pkthdr->reply_port = htonl(pkthdr->reply_port);
    pkthdr->mtu = htonl(pkthdr->mtu);
    pkthdr->fragment_nr = htonl(pkthdr->fragment_nr);
}

void
packet_header_ntoh (jacknet_packet_header *pkthdr)
{
    pkthdr->capture_channels_audio = ntohl(pkthdr->capture_channels_audio);
    pkthdr->playback_channels_audio = ntohl(pkthdr->playback_channels_audio);
    pkthdr->capture_channels_midi = ntohl(pkthdr->capture_channels_midi);
    pkthdr->playback_channels_midi = ntohl(pkthdr->playback_channels_midi);
    pkthdr->period_size = ntohl(pkthdr->period_size);
    pkthdr->sample_rate = ntohl(pkthdr->sample_rate);
    pkthdr->sync_state = ntohl(pkthdr->sync_state);
    pkthdr->transport_frame = ntohl(pkthdr->transport_frame);
    pkthdr->transport_state = ntohl(pkthdr->transport_state);
    pkthdr->framecnt = ntohl(pkthdr->framecnt);
    pkthdr->latency = ntohl(pkthdr->latency);
    pkthdr->reply_port = ntohl(pkthdr->reply_port);
    pkthdr->mtu = ntohl(pkthdr->mtu);
    pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr);
}

int get_sample_size (int bitdepth)
{
    if (bitdepth == 8)
        return sizeof (int8_t);
    if (bitdepth == 16)
        return sizeof (int16_t);
    //JN: why? is this for buffer sizes before or after encoding?
    //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N?
    if( bitdepth == OPUS_MODE )
        return sizeof( unsigned char );
    return sizeof (int32_t);
}

int jack_port_is_audio(const char *porttype)
{
    return (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0);
}

int jack_port_is_midi(const char *porttype)
{
    return (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0);
}


// fragment management functions.

packet_cache
*packet_cache_new (int num_packets, int pkt_size, int mtu)
{
    int fragment_payload_size = mtu - sizeof (jacknet_packet_header);
    int i, fragment_number;

    if( pkt_size == sizeof(jacknet_packet_header) )
        fragment_number = 1;
    else
        fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1;

    packet_cache *pcache = malloc (sizeof (packet_cache));
    if (pcache == NULL) {
        jack_error ("could not allocate packet cache (1)");
        return NULL;
    }

    pcache->size = num_packets;
    pcache->packets = malloc (sizeof (cache_packet) * num_packets);
    pcache->master_address_valid = 0;
    pcache->last_framecnt_retreived = 0;
    pcache->last_framecnt_retreived_valid = 0;

    if (pcache->packets == NULL) {
        jack_error ("could not allocate packet cache (2)");
        return NULL;
    }

    for (i = 0; i < num_packets; i++) {
        pcache->packets[i].valid = 0;
        pcache->packets[i].num_fragments = fragment_number;
        pcache->packets[i].packet_size = pkt_size;
        pcache->packets[i].mtu = mtu;
        pcache->packets[i].framecnt = 0;
        pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number);
        pcache->packets[i].packet_buf = malloc (pkt_size);
        if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) {
            jack_error ("could not allocate packet cache (3)");
            return NULL;
        }
    }
    pcache->mtu = mtu;

    return pcache;
}

void
packet_cache_free (packet_cache *pcache)
{
    int i;
    if( pcache == NULL )
        return;

    for (i = 0; i < pcache->size; i++) {
        free (pcache->packets[i].fragment_array);
        free (pcache->packets[i].packet_buf);
    }

    free (pcache->packets);
    free (pcache);
}

cache_packet
*packet_cache_get_packet (packet_cache *pcache, jack_nframes_t framecnt)
{
    int i;
    cache_packet *retval;

    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt))
            return &(pcache->packets[i]);
    }

    // The Packet is not in the packet cache.
    // find a free packet.

    retval = packet_cache_get_free_packet (pcache);
    if (retval != NULL) {
        cache_packet_set_framecnt (retval, framecnt);
        return retval;
    }

    // No Free Packet available
    // Get The Oldest packet and reset it.

    retval = packet_cache_get_oldest_packet (pcache);
    //printf( "Dropping %d from Cache :S\n", retval->framecnt );
    cache_packet_reset (retval);
    cache_packet_set_framecnt (retval, framecnt);

    return retval;
}

// TODO: fix wrapping case... need to pass
//       current expected frame here.
//
//       or just save framecount into packet_cache.

cache_packet
*packet_cache_get_oldest_packet (packet_cache *pcache)
{
    jack_nframes_t minimal_frame = JACK_MAX_FRAMES;
    cache_packet *retval = &(pcache->packets[0]);
    int i;

    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) {
            minimal_frame = pcache->packets[i].framecnt;
            retval = &(pcache->packets[i]);
        }
    }

    return retval;
}

cache_packet
*packet_cache_get_free_packet (packet_cache *pcache)
{
    int i;

    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid == 0)
            return &(pcache->packets[i]);
    }

    return NULL;
}

void
cache_packet_reset (cache_packet *pack)
{
    int i;
    pack->valid = 0;

    // XXX: i don't think this is necessary here...
    //      fragment array is cleared in _set_framecnt()

    for (i = 0; i < pack->num_fragments; i++)
        pack->fragment_array[i] = 0;
}

void
cache_packet_set_framecnt (cache_packet *pack, jack_nframes_t framecnt)
{
    int i;

    pack->framecnt = framecnt;

    for (i = 0; i < pack->num_fragments; i++)
        pack->fragment_array[i] = 0;

    pack->valid = 1;
}

void
cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len)
{
    jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
    int fragment_payload_size = pack->mtu - sizeof (jacknet_packet_header);
    char *packet_bufX = pack->packet_buf + sizeof (jacknet_packet_header);
    char *dataX = packet_buf + sizeof (jacknet_packet_header);

    jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr);
    jack_nframes_t framecnt    = ntohl (pkthdr->framecnt);

    if (framecnt != pack->framecnt) {
        jack_error ("error. framecnts don't match");
        return;
    }

    if (fragment_nr == 0) {
        memcpy (pack->packet_buf, packet_buf, rcv_len);
        pack->fragment_array[0] = 1;

        return;
    }

    if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) {
        if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) {
            memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header));
            pack->fragment_array[fragment_nr] = 1;
        } else
            jack_error ("too long packet received...");
    }
}

int
cache_packet_is_complete (cache_packet *pack)
{
    int i;
    for (i = 0; i < pack->num_fragments; i++)
        if (pack->fragment_array[i] == 0)
            return 0;

    return 1;
}

#ifndef WIN32
// new poll using nanoseconds resolution and
// not waiting forever.
int
netjack_poll_deadline (int sockfd, jack_time_t deadline)
{
    struct pollfd fds;
    int poll_err = 0;
#if HAVE_PPOLL
    struct timespec timeout_spec = { 0, 0 };
#else
    int timeout;
#endif

    jack_time_t now = jack_get_time();
    if( now >= deadline )
        return 0;

    if( (deadline - now) >= 1000000 ) {
        jack_error( "deadline more than 1 second in the future, trimming it." );
        deadline = now + 500000;
    }
#if HAVE_PPOLL
    timeout_spec.tv_nsec = (deadline - now) * 1000;
#else
    timeout = lrintf( (float)(deadline - now) / 1000.0 );
#endif

    fds.fd = sockfd;
    fds.events = POLLIN;

#if HAVE_PPOLL
    poll_err = ppoll (&fds, 1, &timeout_spec, NULL);
#else
    poll_err = poll (&fds, 1, timeout);
#endif

    if (poll_err == -1) {
        switch (errno) {
            case EBADF:
                jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
                break;
            case EFAULT:
                jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
                break;
            case EINTR:
                jack_error ("Error %d: A signal occurred before any requested event", errno);
                break;
            case EINVAL:
                jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
                break;
            case ENOMEM:
                jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
                break;
        }
    }
    return poll_err;
}

int
netjack_poll (int sockfd, int timeout)
{
    struct pollfd fds;
    int i, poll_err = 0;
    sigset_t sigmask, rsigmask;
    struct sigaction action;

    sigemptyset(&sigmask);
    sigaddset(&sigmask, SIGHUP);
    sigaddset(&sigmask, SIGINT);
    sigaddset(&sigmask, SIGQUIT);
    sigaddset(&sigmask, SIGPIPE);
    sigaddset(&sigmask, SIGTERM);
    sigaddset(&sigmask, SIGUSR1);
    sigaddset(&sigmask, SIGUSR2);

    action.sa_handler = SIG_DFL;
    action.sa_mask = sigmask;
    action.sa_flags = SA_RESTART;

    for (i = 1; i < NSIG; i++)
        if (sigismember (&sigmask, i))
            sigaction (i, &action, 0);

    fds.fd = sockfd;
    fds.events = POLLIN;

    sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask);
    while (poll_err == 0) {
        poll_err = poll (&fds, 1, timeout);
    }
    sigprocmask(SIG_SETMASK, &rsigmask, NULL);

    if (poll_err == -1) {
        switch (errno) {
            case EBADF:
                jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
                break;
            case EFAULT:
                jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
                break;
            case EINTR:
                jack_error ("Error %d: A signal occurred before any requested event", errno);
                break;
            case EINVAL:
                jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
                break;
            case ENOMEM:
                jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
                break;
        }
        return 0;
    }
    return 1;
}

#else
int
netjack_poll (int sockfd, int timeout)
{
    jack_error( "netjack_poll not implemented" );
    return 0;
}
int
netjack_poll_deadline (int sockfd, jack_time_t deadline)
{
    fd_set fds;
    FD_ZERO( &fds );
    FD_SET( sockfd, &fds );

    struct timeval timeout;
    while( 1 ) {
        jack_time_t now = jack_get_time();
        if( now >= deadline )
            return 0;

        int timeout_usecs = (deadline - now);
        //jack_error( "timeout = %d", timeout_usecs );
        timeout.tv_sec = 0;
        timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs;
        timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs;

        int poll_err = select (0, &fds, NULL, NULL, &timeout);
        if( poll_err != 0 )
            return poll_err;
    }

    return 0;
}
#endif
// This now reads all a socket has into the cache.
// replacing netjack_recv functions.

void
packet_cache_drain_socket( packet_cache *pcache, int sockfd )
{
    char *rx_packet = alloca (pcache->mtu);
    jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet;
    int rcv_len;
    jack_nframes_t framecnt;
    cache_packet *cpack;
    struct sockaddr_in sender_address;
#ifdef WIN32
    int senderlen = sizeof( struct sockaddr_in );
    u_long parm = 1;
    ioctlsocket( sockfd, FIONBIO, &parm );
#else
    unsigned int senderlen = sizeof( struct sockaddr_in );
#endif
    while (1) {
#ifdef WIN32
        rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0,
                            (struct sockaddr*) &sender_address, &senderlen);
#else
        rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT,
                            (struct sockaddr*) &sender_address, &senderlen);
#endif
        if (rcv_len < 0)
            return;

        if (pcache->master_address_valid) {
            // Verify its from our master.
            if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0)
                continue;
        } else {
            // Setup this one as master
            //printf( "setup master...\n" );
            memcpy ( &(pcache->master_address), &sender_address, senderlen );
            pcache->master_address_valid = 1;
        }

        framecnt = ntohl (pkthdr->framecnt);
        if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
            continue;

        cpack = packet_cache_get_packet (pcache, framecnt);
        cache_packet_add_fragment (cpack, rx_packet, rcv_len);
        cpack->recv_timestamp = jack_get_time();
    }
}

void
packet_cache_reset_master_address( packet_cache *pcache )
{
    pcache->master_address_valid = 0;
    pcache->last_framecnt_retreived = 0;
    pcache->last_framecnt_retreived_valid = 0;
}

void
packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt )
{
    int i;

    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) {
            cache_packet_reset (&(pcache->packets[i]));
        }
    }
}

int
packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp )
{
    int i;
    cache_packet *cpack = NULL;


    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) {
            cpack = &(pcache->packets[i]);
            break;
        }
    }

    if( cpack == NULL ) {
        //printf( "retrieve packet: %d....not found\n", framecnt );
        return -1;
    }

    if( !cache_packet_is_complete( cpack ) ) {
        return -1;
    }

    // ok. cpack is the one we want and its complete.
    *packet_buf = cpack->packet_buf;
    if( timestamp )
        *timestamp = cpack->recv_timestamp;

    pcache->last_framecnt_retreived_valid = 1;
    pcache->last_framecnt_retreived = framecnt;

    return pkt_size;
}

int
packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt )
{
    int i;
    cache_packet *cpack = NULL;


    for (i = 0; i < pcache->size; i++) {
        if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) {
            cpack = &(pcache->packets[i]);
            break;
        }
    }

    if( cpack == NULL ) {
        //printf( "retrieve packet: %d....not found\n", framecnt );
        return -1;
    }

    if( !cache_packet_is_complete( cpack ) ) {
        return -1;
    }

    cache_packet_reset (cpack);
    packet_cache_clear_old_packets( pcache, framecnt );

    return 0;
}
float
packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt )
{
    int num_packets_before_us = 0;
    int i;

    for (i = 0; i < pcache->size; i++) {
        cache_packet *cpack = &(pcache->packets[i]);
        if (cpack->valid && cache_packet_is_complete( cpack ))
            if( cpack->framecnt >= expected_framecnt )
                num_packets_before_us += 1;
    }

    return 100.0 * (float)num_packets_before_us / (float)( pcache->size );
}

// Returns 0 when no valid packet is inside the cache.
int
packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt )
{
    int i;
    jack_nframes_t best_offset = JACK_MAX_FRAMES / 2 - 1;
    int retval = 0;

    for (i = 0; i < pcache->size; i++) {
        cache_packet *cpack = &(pcache->packets[i]);
        //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );

        if (!cpack->valid || !cache_packet_is_complete( cpack )) {
            //printf( "invalid\n" );
            continue;
        }

        if( cpack->framecnt < expected_framecnt )
            continue;

        if( (cpack->framecnt - expected_framecnt) > best_offset ) {
            continue;
        }

        best_offset = cpack->framecnt - expected_framecnt;
        retval = 1;

        if (best_offset == 0)
            break;
    }
    if (retval && framecnt)
        *framecnt = expected_framecnt + best_offset;

    return retval;
}

int
packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt )
{
    int i;
    jack_nframes_t best_value = 0;
    int retval = 0;

    for (i = 0; i < pcache->size; i++) {
        cache_packet *cpack = &(pcache->packets[i]);
        //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );

        if (!cpack->valid || !cache_packet_is_complete( cpack )) {
            //printf( "invalid\n" );
            continue;
        }

        if (cpack->framecnt < best_value) {
            continue;
        }

        best_value = cpack->framecnt;
        retval = 1;

    }
    if (retval && framecnt)
        *framecnt = best_value;

    return retval;
}

// Returns 0 when no valid packet is inside the cache.
int
packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt )
{
    int i;
    jack_nframes_t best_offset = 0;
    int retval = 0;

    for (i = 0; i < pcache->size; i++) {
        cache_packet *cpack = &(pcache->packets[i]);
        //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );

        if (!cpack->valid || !cache_packet_is_complete( cpack )) {
            //printf( "invalid\n" );
            continue;
        }

        if ((cpack->framecnt - expected_framecnt) < best_offset) {
            continue;
        }

        best_offset = cpack->framecnt - expected_framecnt;
        retval = 1;

        if( best_offset == 0 )
            break;
    }
    if (retval && framecnt)
        *framecnt = JACK_MAX_FRAMES - best_offset;

    return retval;
}
// fragmented packet IO
void
netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu)
{
    int frag_cnt = 0;
    char *tx_packet, *dataX;
    jacknet_packet_header *pkthdr;

    tx_packet = alloca (mtu + 10);
    dataX = tx_packet + sizeof (jacknet_packet_header);
    pkthdr = (jacknet_packet_header *) tx_packet;

    int fragment_payload_size = mtu - sizeof (jacknet_packet_header);

    if (pkt_size <= mtu) {
        int err;
        pkthdr = (jacknet_packet_header *) packet_buf;
        pkthdr->fragment_nr = htonl (0);
        err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
        if( err < 0 ) {
            //printf( "error in send\n" );
            perror( "send" );
        }
    } else {
        int err;
        // Copy the packet header to the tx pack first.
        memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header));

        // Now loop and send all
        char *packet_bufX = packet_buf + sizeof (jacknet_packet_header);

        while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) {
            pkthdr->fragment_nr = htonl (frag_cnt++);
            memcpy (dataX, packet_bufX, fragment_payload_size);
            sendto (sockfd, tx_packet, mtu, flags, addr, addr_size);
            packet_bufX += fragment_payload_size;
        }

        int last_payload_size = packet_buf + pkt_size - packet_bufX;
        memcpy (dataX, packet_bufX, last_payload_size);
        pkthdr->fragment_nr = htonl (frag_cnt);
        //jack_log("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size);

        // sendto(last_pack_size);
        err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size);
        if( err < 0 ) {
            //printf( "error in send\n" );
            perror( "send" );
        }
    }
}

void
decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf)
{
    int i;
    jack_midi_clear_buffer (buf);
    for (i = 0; i < buffer_size_uint32 - 3;) {
        uint32_t payload_size;
        payload_size = buffer_uint32[i];
        payload_size = ntohl (payload_size);
        if (payload_size) {
            jack_midi_event_t event;
            event.time = ntohl (buffer_uint32[i + 1]);
            event.size = ntohl (buffer_uint32[i + 2]);
            event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i + 3]));
            jack_midi_event_write (buf, event.time, event.buffer, event.size);

            // skip to the next event
            unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1;
            i += 3 + nb_data_quads;
        } else
            break; // no events can follow an empty event, we're done
    }
}

void
encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf)
{
    int i;
    unsigned int written = 0;
    // midi port, encode midi events
    unsigned int nevents = jack_midi_get_event_count (buf);
    for (i = 0; i < nevents; ++i) {
        jack_midi_event_t event;
        jack_midi_event_get (&event, buf, i);
        unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1;
        unsigned int payload_size = 3 + nb_data_quads;
        // only write if we have sufficient space for the event
        // otherwise drop it
        if (written + payload_size < buffer_size_uint32 - 1) {
            // write header
            buffer_uint32[written] = htonl (payload_size);
            written++;
            buffer_uint32[written] = htonl (event.time);
            written++;
            buffer_uint32[written] = htonl (event.size);
            written++;

            // write data
            jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written]));
            memcpy (tmpbuff, event.buffer, event.size);
            written += nb_data_quads;
        } else {
            // buffer overflow
            jack_error ("midi buffer overflow");
            break;
        }
    }
    // now put a netjack_midi 'no-payload' event, signaling EOF
    buffer_uint32[written] = 0;
}

// render functions for float
void
render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
{
    int chn = 0;
    JSList *node = capture_ports;
    JSList *src_node = capture_srcs;

    uint32_t *packet_bufX = (uint32_t *)packet_payload;

    if (!packet_payload)
        return;

    while (node != NULL) {
        int i;
        int_float_t val;
        SRC_DATA src;

        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, resample if necessary
            if (net_period_down != nframes) {
                SRC_STATE *src_state = src_node->data;
                for (i = 0; i < net_period_down; i++) {
                    packet_bufX[i] = ntohl (packet_bufX[i]);
                }

                src.data_in = (float *) packet_bufX;
                src.input_frames = net_period_down;

                src.data_out = buf;
                src.output_frames = nframes;

                src.src_ratio = (float) nframes / (float) net_period_down;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);
                src_node = jack_slist_next (src_node);
            } else
            {
                if( dont_htonl_floats ) {
                    memcpy( buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t));
                } else {
                    for (i = 0; i < net_period_down; i++) {
                        val.i = packet_bufX[i];
                        val.i = ntohl (val.i);
                        buf[i] = val.f;
                    }
                }
            }
        } else if (jack_port_is_midi (porttype)) {
            // midi port, decode midi events
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_down;
            uint32_t * buffer_uint32 = (uint32_t*)packet_bufX;
            decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_down);
        node = jack_slist_next (node);
        chn++;
    }
}

void
render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats )
{
    int chn = 0;
    JSList *node = playback_ports;
    JSList *src_node = playback_srcs;

    uint32_t *packet_bufX = (uint32_t *) packet_payload;

    while (node != NULL) {
        SRC_DATA src;
        int i;
        int_float_t val;
        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, resample if necessary

            if (net_period_up != nframes) {
                SRC_STATE *src_state = src_node->data;
                src.data_in = buf;
                src.input_frames = nframes;

                src.data_out = (float *) packet_bufX;
                src.output_frames = net_period_up;

                src.src_ratio = (float) net_period_up / (float) nframes;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);

                for (i = 0; i < net_period_up; i++) {
                    packet_bufX[i] = htonl (packet_bufX[i]);
                }
                src_node = jack_slist_next (src_node);
            } else
            {
                if( dont_htonl_floats ) {
                    memcpy( packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t) );
                } else {
                    for (i = 0; i < net_period_up; i++) {
                        val.f = buf[i];
                        val.i = htonl (val.i);
                        packet_bufX[i] = val.i;
                    }
                }
            }
        } else if (jack_port_is_midi (porttype)) {
            // encode midi events from port to packet
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_up;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_up);
        node = jack_slist_next (node);
        chn++;
    }
}

// render functions for 16bit
void
render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
    int chn = 0;
    JSList *node = capture_ports;
    JSList *src_node = capture_srcs;

    uint16_t *packet_bufX = (uint16_t *)packet_payload;

    if( !packet_payload )
        return;

    while (node != NULL) {
        int i;
        //uint32_t val;
        SRC_DATA src;

        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

        float *floatbuf = alloca (sizeof(float) * net_period_down);
        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, resample if necessary

            if (net_period_down != nframes) {
                SRC_STATE *src_state = src_node->data;
                for (i = 0; i < net_period_down; i++) {
                    floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0;
                }

                src.data_in = floatbuf;
                src.input_frames = net_period_down;

                src.data_out = buf;
                src.output_frames = nframes;

                src.src_ratio = (float) nframes / (float) net_period_down;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);
                src_node = jack_slist_next (src_node);
            } else
                for (i = 0; i < net_period_down; i++)
                    buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0;
        } else if (jack_port_is_midi (porttype)) {
            // midi port, decode midi events
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_down / 2;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_down);
        node = jack_slist_next (node);
        chn++;
    }
}

void
render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
    int chn = 0;
    JSList *node = playback_ports;
    JSList *src_node = playback_srcs;

    uint16_t *packet_bufX = (uint16_t *)packet_payload;

    while (node != NULL) {
        SRC_DATA src;
        int i;
        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, resample if necessary

            if (net_period_up != nframes) {
                SRC_STATE *src_state = src_node->data;

                float *floatbuf = alloca (sizeof(float) * net_period_up);

                src.data_in = buf;
                src.input_frames = nframes;

                src.data_out = floatbuf;
                src.output_frames = net_period_up;

                src.src_ratio = (float) net_period_up / (float) nframes;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);

                for (i = 0; i < net_period_up; i++) {
                    packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0)));
                }
                src_node = jack_slist_next (src_node);
            } else
                for (i = 0; i < net_period_up; i++)
                    packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0)));
        } else if (jack_port_is_midi (porttype)) {
            // encode midi events from port to packet
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_up / 2;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_up);
        node = jack_slist_next (node);
        chn++;
    }
}

// render functions for 8bit
void
render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
    int chn = 0;
    JSList *node = capture_ports;

    JSList *src_node = capture_srcs;

    int8_t *packet_bufX = (int8_t *)packet_payload;

    if (!packet_payload)
        return;

    while (node != NULL) {
        int i;
        //uint32_t val;
        SRC_DATA src;

        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

        float *floatbuf = alloca (sizeof (float) * net_period_down);
        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio(porttype)) {
            // audio port, resample if necessary
            if (net_period_down != nframes) {
                SRC_STATE *src_state = src_node->data;
                for (i = 0; i < net_period_down; i++)
                    floatbuf[i] = ((float) packet_bufX[i]) / 127.0;

                src.data_in = floatbuf;
                src.input_frames = net_period_down;

                src.data_out = buf;
                src.output_frames = nframes;

                src.src_ratio = (float) nframes / (float) net_period_down;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);
                src_node = jack_slist_next (src_node);
            } else
                for (i = 0; i < net_period_down; i++)
                    buf[i] = ((float) packet_bufX[i]) / 127.0;
        } else if (jack_port_is_midi (porttype)) {
            // midi port, decode midi events
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_down / 2;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_down);
        node = jack_slist_next (node);
        chn++;
    }
}

void
render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
    int chn = 0;
    JSList *node = playback_ports;
    JSList *src_node = playback_srcs;

    int8_t *packet_bufX = (int8_t *)packet_payload;

    while (node != NULL) {
        SRC_DATA src;
        int i;
        jack_port_t *port = (jack_port_t *) node->data;

        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, resample if necessary
            if (net_period_up != nframes) {

                SRC_STATE *src_state = src_node->data;

                float *floatbuf = alloca (sizeof (float) * net_period_up);

                src.data_in = buf;
                src.input_frames = nframes;

                src.data_out = floatbuf;
                src.output_frames = net_period_up;

                src.src_ratio = (float) net_period_up / (float) nframes;
                src.end_of_input = 0;

                src_set_ratio (src_state, src.src_ratio);
                src_process (src_state, &src);

                for (i = 0; i < net_period_up; i++)
                    packet_bufX[i] = floatbuf[i] * 127.0;
                src_node = jack_slist_next (src_node);
            } else
                for (i = 0; i < net_period_up; i++)
                    packet_bufX[i] = buf[i] * 127.0;
        } else if (jack_port_is_midi (porttype)) {
            // encode midi events from port to packet
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_up / 4;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_up);
        node = jack_slist_next (node);
        chn++;
    }
}

#if HAVE_OPUS
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
// render functions for Opus.
void
render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
{
    int chn = 0;
    JSList *node = capture_ports;
    JSList *src_node = capture_srcs;

    unsigned char *packet_bufX = (unsigned char *)packet_payload;

    while (node != NULL) {
        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);

        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, decode opus data.
            OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
            if( !packet_payload )
                memset(buf, 0, nframes * sizeof(float));
            else {
                unsigned short len;
                memcpy(&len, packet_bufX, CDO);
                len = ntohs(len);
                opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
            }

            src_node = jack_slist_next (src_node);
        } else if (jack_port_is_midi (porttype)) {
            // midi port, decode midi events
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_down / 2;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            if( packet_payload )
                decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_down);
        node = jack_slist_next (node);
        chn++;
    }
}

void
render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
{
    int chn = 0;
    JSList *node = playback_ports;
    JSList *src_node = playback_srcs;

    unsigned char *packet_bufX = (unsigned char *)packet_payload;

    while (node != NULL) {
        jack_port_t *port = (jack_port_t *) node->data;
        jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
        const char *porttype = jack_port_type (port);

        if (jack_port_is_audio (porttype)) {
            // audio port, encode opus data.

            int encoded_bytes;
            float *floatbuf = alloca (sizeof(float) * nframes );
            memcpy( floatbuf, buf, nframes * sizeof(float) );
            OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
            encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
            unsigned short len = htons(encoded_bytes);
            memcpy(packet_bufX, &len, CDO);
            src_node = jack_slist_next( src_node );
        } else if (jack_port_is_midi (porttype)) {
            // encode midi events from port to packet
            // convert the data buffer to a standard format (uint32_t based)
            unsigned int buffer_size_uint32 = net_period_up / 2;
            uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
            encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
        }
        packet_bufX = (packet_bufX + net_period_up);
        node = jack_slist_next (node);
        chn++;
    }
}
#endif

/* Wrapper functions with bitdepth argument... */
void
render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
{
    if (bitdepth == 8)
        render_payload_to_jack_ports_8bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
    else if (bitdepth == 16)
        render_payload_to_jack_ports_16bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#if HAVE_OPUS
    else if (bitdepth == OPUS_MODE)
        render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
#endif
    else
        render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
}

void
render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats)
{
    if (bitdepth == 8)
        render_jack_ports_to_payload_8bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
    else if (bitdepth == 16)
        render_jack_ports_to_payload_16bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#if HAVE_OPUS
    else if (bitdepth == OPUS_MODE)
        render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
#endif
    else
        render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
}
0707010000000E000081A400000000000000000000000161E2F7EE000015D2000000000000000000000000000000000000002D00000000jack-example-tools-1/common/netjack_packet.h
/*
 * NetJack - Packet Handling functions
 *
 * used by the driver and the jacknet_client
 *
 * Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $
 *
 */

#ifndef __JACK_NET_PACKET_H__
#define __JACK_NET_PACKET_H__

#ifdef __cplusplus
extern "C"
{
#endif

#include <jack/jack.h>
#include <jack/types.h>
#include <jack/jslist.h>
#include <jack/midiport.h>

// The Packet Header.

#define OPUS_MODE  999   // Magic bitdepth value that indicates OPUS compression
#define MASTER_FREEWHEELS 0x80000000

    typedef struct _jacknet_packet_header jacknet_packet_header;

    struct _jacknet_packet_header {
        // General AutoConf Data
        jack_nframes_t capture_channels_audio;
        jack_nframes_t playback_channels_audio;
        jack_nframes_t capture_channels_midi;
        jack_nframes_t playback_channels_midi;
        jack_nframes_t period_size;
        jack_nframes_t sample_rate;

        // Transport Sync
        jack_nframes_t sync_state;
        jack_nframes_t transport_frame;
        jack_nframes_t transport_state;

        // Packet loss Detection, and latency reduction
        jack_nframes_t framecnt;
        jack_nframes_t latency;

        jack_nframes_t reply_port;
        jack_nframes_t mtu;
        jack_nframes_t fragment_nr;
    };

    typedef union _int_float int_float_t;

    union _int_float {
        uint32_t i;
        float    f;
    };

    // fragment reorder cache.
    typedef struct _cache_packet cache_packet;

    struct _cache_packet {
        int		    valid;
        int		    num_fragments;
        int		    packet_size;
        int		    mtu;
        jack_time_t	    recv_timestamp;
        jack_nframes_t  framecnt;
        char *	    fragment_array;
        char *	    packet_buf;
    };

    typedef struct _packet_cache packet_cache;

    struct _packet_cache {
        int size;
        cache_packet *packets;
        int mtu;
        struct sockaddr_in master_address;
        int master_address_valid;
        jack_nframes_t last_framecnt_retreived;
        int last_framecnt_retreived_valid;
    };

    // fragment cache function prototypes
    // XXX: Some of these are private.
    packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu);
    void	      packet_cache_free(packet_cache *pkt_cache);

    cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt);
    cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache);
    cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache);

    void	cache_packet_reset(cache_packet *pack);
    void	cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt);
    void	cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len);
    int	cache_packet_is_complete(cache_packet *pack);

    void packet_cache_drain_socket( packet_cache *pcache, int sockfd );
    void packet_cache_reset_master_address( packet_cache *pcache );
    float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt );
    int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp );
    int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt );
    int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );
    int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt );
    int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );

    // Function Prototypes

    int netjack_poll_deadline (int sockfd, jack_time_t deadline);
    void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu);
    int get_sample_size(int bitdepth);
    void packet_header_hton(jacknet_packet_header *pkthdr);
    void packet_header_ntoh(jacknet_packet_header *pkthdr);
    void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats );
    void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats );

    // XXX: This is sort of deprecated:
    //      This one waits forever. an is not using ppoll
    int netjack_poll(int sockfd, int timeout);

    void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);
    void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);

#ifdef __cplusplus
}
#endif
#endif

0707010000000F000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000002500000000jack-example-tools-1/example-clients07070100000010000081A400000000000000000000000161E2F7EE000001B5000000000000000000000000000000000000003000000000jack-example-tools-1/example-clients/.gitignore.deps/
.libs/
Makefile
Makefile.in
capture_client.o
impulse_grabber.o
inprocess.la
inprocess.lo
intime.la
intime.lo
jack_impulse_grabber
jack_latent_client
jack_metro
jack_midiseq
jack_midisine
jack_rec
jack_server_control
jack_showtime
jack_simple_client
jack_simple_session_client
jack_transport_client
latent_client.o
metro.o
midiseq.o
midisine.o
server_control.o
showtime.o
simple_client.o
simple_session_client.o
transport_client.o
07070100000011000081A400000000000000000000000161E2F7EE00002449000000000000000000000000000000000000003600000000jack-example-tools-1/example-clients/capture_client.c/*
    Copyright (C) 2001 Paul Davis
    Copyright (C) 2003 Jack O'Quin

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    * 2002/08/23 - modify for libsndfile 1.0.0 <andy@alsaplayer.org>
    * 2003/05/26 - use ringbuffers - joq
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sndfile.h>
#include <pthread.h>
#include <signal.h>
#include <getopt.h>
#include <inttypes.h>

#include <jack/jack.h>
#include <jack/ringbuffer.h>

typedef struct _thread_info {
	pthread_t thread_id;
	SNDFILE *sf;
	jack_nframes_t duration;
	jack_nframes_t rb_size;
	jack_client_t *client;
	unsigned int channels;
	int bitdepth;
	char *path;
	volatile int can_capture;
	volatile int can_process;
	volatile int status;
} jack_thread_info_t;

/* JACK data */
unsigned int nports;
jack_port_t **ports;
jack_default_audio_sample_t **in;
jack_nframes_t nframes;
const size_t sample_size = sizeof(jack_default_audio_sample_t);

/* Synchronization between process thread and disk thread. */
#define DEFAULT_RB_SIZE 16384		/* ringbuffer size in frames */
jack_ringbuffer_t *rb;
pthread_mutex_t disk_thread_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  data_ready = PTHREAD_COND_INITIALIZER;
long overruns = 0;
jack_client_t *client;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void *
disk_thread (void *arg)
{
	jack_thread_info_t *info = (jack_thread_info_t *) arg;
	static jack_nframes_t total_captured = 0;
	jack_nframes_t samples_per_frame = info->channels;
	size_t bytes_per_frame = samples_per_frame * sample_size;
	void *framebuf = malloc (bytes_per_frame);

	pthread_mutex_lock (&disk_thread_lock);

	info->status = 0;

	while (1) {

		/* Write the data one frame at a time.  This is
		 * inefficient, but makes things simpler. */
		while (info->can_capture &&
		       (jack_ringbuffer_read_space (rb) >= bytes_per_frame)) {

			jack_ringbuffer_read (rb, framebuf, bytes_per_frame);

			if (sf_writef_float (info->sf, framebuf, 1) != 1) {
				char errstr[256];
				sf_error_str (0, errstr, sizeof (errstr) - 1);
				fprintf (stderr,
					 "cannot write sndfile (%s)\n",
					 errstr);
				info->status = EIO; /* write failed */
				goto done;
			}

			if (++total_captured >= info->duration) {
				printf ("disk thread finished\n");
				goto done;
			}
		}

		/* wait until process() signals more data */
		pthread_cond_wait (&data_ready, &disk_thread_lock);
	}

 done:
	pthread_mutex_unlock (&disk_thread_lock);
	free (framebuf);
	return 0;
}

static int
process (jack_nframes_t nframes, void *arg)
{
	unsigned chn;
	size_t i;
	jack_thread_info_t *info = (jack_thread_info_t *) arg;

	/* Do nothing until we're ready to begin. */
	if ((!info->can_process) || (!info->can_capture))
		return 0;

	for (chn = 0; chn < nports; chn++)
		in[chn] = jack_port_get_buffer (ports[chn], nframes);

	/* Sndfile requires interleaved data.  It is simpler here to
	 * just queue interleaved samples to a single ringbuffer. */
	for (i = 0; i < nframes; i++) {
		for (chn = 0; chn < nports; chn++) {
			if (jack_ringbuffer_write (rb, (void *) (in[chn]+i),
					      sample_size)
			    < sample_size)
				overruns++;
		}
	}

	/* Tell the disk thread there is work to do.  If it is already
	 * running, the lock will not be available.  We can't wait
	 * here in the process() thread, but we don't need to signal
	 * in that case, because the disk thread will read all the
	 * data queued before waiting again. */
	if (pthread_mutex_trylock (&disk_thread_lock) == 0) {
		pthread_cond_signal (&data_ready);
		pthread_mutex_unlock (&disk_thread_lock);
	}

	return 0;
}

static void
jack_shutdown (void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

static void
setup_disk_thread (jack_thread_info_t *info)
{
	SF_INFO sf_info;
	int short_mask;

	sf_info.samplerate = jack_get_sample_rate (info->client);
	sf_info.channels = info->channels;

	switch (info->bitdepth) {
		case 8: short_mask = SF_FORMAT_PCM_U8;
		  	break;
		case 16: short_mask = SF_FORMAT_PCM_16;
			 break;
		case 24: short_mask = SF_FORMAT_PCM_24;
			 break;
		case 32: short_mask = SF_FORMAT_PCM_32;
			 break;
		default: short_mask = SF_FORMAT_PCM_16;
			 break;
	}
	sf_info.format = SF_FORMAT_WAV|short_mask;

	if ((info->sf = sf_open (info->path, SFM_WRITE, &sf_info)) == NULL) {
		char errstr[256];
		sf_error_str (0, errstr, sizeof (errstr) - 1);
		fprintf (stderr, "cannot open sndfile \"%s\" for output (%s)\n", info->path, errstr);
		jack_client_close (info->client);
		exit (1);
	}

	info->duration *= sf_info.samplerate;
	info->can_capture = 0;

	pthread_create (&info->thread_id, NULL, disk_thread, info);
}

static void
run_disk_thread (jack_thread_info_t *info)
{
	info->can_capture = 1;
	pthread_join (info->thread_id, NULL);
	sf_close (info->sf);
	if (overruns > 0) {
		fprintf (stderr,
			 "jackrec failed with %ld overruns.\n", overruns);
		fprintf (stderr, " try a bigger buffer than -B %"
			 PRIu32 ".\n", info->rb_size);
		info->status = EPIPE;
	}
}

static void
setup_ports (int sources, char *source_names[], jack_thread_info_t *info)
{
	unsigned int i;
	size_t in_size;

	/* Allocate data structures that depend on the number of ports. */
	nports = sources;
	ports = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports);
	in_size =  nports * sizeof (jack_default_audio_sample_t *);
	in = (jack_default_audio_sample_t **) malloc (in_size);
	rb = jack_ringbuffer_create (nports * sample_size * info->rb_size);

	/* When JACK is running realtime, jack_activate() will have
	 * called mlockall() to lock our pages into memory.  But, we
	 * still need to touch any newly allocated pages before
	 * process() starts using them.  Otherwise, a page fault could
	 * create a delay that would force JACK to shut us down. */
	memset(in, 0, in_size);
	memset(rb->buf, 0, rb->size);

	for (i = 0; i < nports; i++) {
		char name[64];

		sprintf (name, "input%d", i+1);

		if ((ports[i] = jack_port_register (info->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
			fprintf (stderr, "cannot register input port \"%s\"!\n", name);
			jack_client_close (info->client);
			exit (1);
		}
	}

	for (i = 0; i < nports; i++) {
		if (jack_connect (info->client, source_names[i], jack_port_name (ports[i]))) {
			fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]);
			jack_client_close (info->client);
			exit (1);
		}
	}

	info->can_process = 1;		/* process() can start, now */
}

int
main (int argc, char *argv[])
{
	jack_thread_info_t thread_info;
	int c;
	int longopt_index = 0;
	extern int optind, opterr;
	int show_usage = 0;
	char *optstring = "d:f:b:B:h";
	struct option long_options[] = {
		{ "help", 0, 0, 'h' },
		{ "duration", 1, 0, 'd' },
		{ "file", 1, 0, 'f' },
		{ "bitdepth", 1, 0, 'b' },
		{ "bufsize", 1, 0, 'B' },
		{ 0, 0, 0, 0 }
	};

	memset (&thread_info, 0, sizeof (thread_info));
	thread_info.rb_size = DEFAULT_RB_SIZE;
	opterr = 0;

	while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) {
		switch (c) {
		case 1:
			/* getopt signals end of '-' options */
			break;

		case 'h':
			show_usage++;
			break;
		case 'd':
			thread_info.duration = atoi (optarg);
			break;
		case 'f':
			thread_info.path = optarg;
			break;
		case 'b':
			thread_info.bitdepth = atoi (optarg);
			break;
		case 'B':
			thread_info.rb_size = atoi (optarg);
			break;
		default:
			fprintf (stderr, "error\n");
			show_usage++;
			break;
		}
	}

	if (show_usage || thread_info.path == NULL || optind == argc) {
		fprintf (stderr, "usage: jackrec -f filename [ -d second ] [ -b bitdepth ] [ -B bufsize ] port1 [ port2 ... ]\n");
		exit (1);
	}

	if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		exit (1);
	}

	thread_info.client = client;
	thread_info.channels = argc - optind;
	thread_info.can_process = 0;

	setup_disk_thread (&thread_info);

	jack_set_process_callback (client, process, &thread_info);
	jack_on_shutdown (client, jack_shutdown, &thread_info);

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
	}

	setup_ports (argc - optind, &argv[optind], &thread_info);

	/* install a signal handler to properly quits jack client */
#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	run_disk_thread (&thread_info);

	jack_client_close (client);

	jack_ringbuffer_free (rb);

	exit (0);
}
07070100000012000081A400000000000000000000000161E2F7EE0000064E000000000000000000000000000000000000002F00000000jack-example-tools-1/example-clients/control.c/** @file control.c
 *
 * @brief This simple client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#include <jack/jack.h>

jack_client_t *client;
static int reorder = 0;

static int Jack_Graph_Order_Callback(void *arg)
{
	const char **ports;
	int i;

	printf("Jack_Graph_Order_Callback count = %d\n", reorder++);

	ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
	if (ports) {
		for (i = 0;  ports[i]; ++i) {
			printf("name: %s\n", ports[i]);
		}
		jack_free(ports);
	}

	ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
	if (ports) {
		for (i = 0;  ports[i]; ++i) {
			printf("name: %s\n", ports[i]);
		}
		jack_free(ports);
	}

	return 0;
}

int
main (int argc, char *argv[])
{
	jack_options_t options = JackNullOption;
	jack_status_t status;

	/* open a client connection to the JACK server */

	client = jack_client_open("control_client", options, &status);
	if (client == NULL) {
		printf("jack_client_open() failed \n");
		exit(1);
	}

	if (jack_set_graph_order_callback(client, Jack_Graph_Order_Callback, 0) != 0) {
		printf("Error when calling jack_set_graph_order_callback() !\n");
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate(client)) {
		printf("cannot activate client");
		exit(1);
	}

	printf("Type 'q' to quit\n");
	while ((getchar() != 'q')) {}

	jack_client_close(client);
	exit (0);
}
07070100000013000081A400000000000000000000000161E2F7EE0000073F000000000000000000000000000000000000003000000000jack-example-tools-1/example-clients/cpu_load.c/** @file cpu_load.c
 *
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <jack/jack.h>


jack_client_t *client;

static void signal_handler(int sig)
{
    jack_client_close(client);
    fprintf(stderr, "signal received, exiting ...\n");
    exit(0);
}


/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown(void *arg)
{
     exit(1);
}

int
main(int argc, char *argv[])
{
    jack_options_t options = JackNullOption;
    jack_status_t status;

    /* open a client connection to the JACK server */

    client = jack_client_open ("jack_cpu_load", options, &status);
    if (client == NULL) {
        fprintf(stderr, "jack_client_open() failed, "
                  "status = 0x%2.0x\n", status);
        if (status & JackServerFailed) {
            fprintf(stderr, "Unable to connect to JACK server\n");
        }
        exit(1);
    }

    jack_on_shutdown(client, jack_shutdown, 0);

    /* Tell the JACK server that we are ready to roll.  Our
     * process() callback will start running now. */

    if (jack_activate(client)) {
        fprintf(stderr, "cannot activate client");
        exit(1);
    }

    /* install a signal handler to properly quits jack client */
#ifdef WIN32
    signal(SIGINT, signal_handler);
    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);
#else
    signal(SIGQUIT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGHUP, signal_handler);
    signal(SIGINT, signal_handler);
#endif

    while (1) {
        printf("jack DSP load %f\n", jack_cpu_load(client));
#ifdef WIN32
        Sleep(1000);
#else
        sleep(1);
#endif
    }

    jack_client_close(client);
    exit(0 );
}
07070100000014000081A400000000000000000000000161E2F7EE0000185A000000000000000000000000000000000000003700000000jack-example-tools-1/example-clients/impulse_grabber.c/*
 *     Copyright (C) 2001 Steve Harris
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <stdlib.h>
#include <signal.h>
#include <math.h>
#include <getopt.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;

unsigned int impulse_sent = 0;
float *response;
unsigned long response_duration;
unsigned long response_pos;
int grab_finished = 0;
jack_client_t *client;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static int
process (jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
	jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes);
	unsigned int i;

	if (grab_finished) {
		return 0;
	} else if (impulse_sent) {
		for(i=0; i<nframes && response_pos < response_duration; i++) {
			response[response_pos++] = in[i];
		}
		if (response_pos >=  response_duration) {
			grab_finished = 1;
		}
		for (i=0; i<nframes; i++) {
			out[i] = 0.0f;
		}
	} else {
		out[0] = 1.0f;
		for (i=1; i<nframes; i++) {
			out[i] = 0.0f;
		}
		impulse_sent = 1;
	}

	return 0;
}

static void
jack_shutdown (void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	float fs;		// The sample rate
	float peak;
	unsigned long peak_sample;
	unsigned int i;
	float duration = 0.0f;
	unsigned int c_format = 0;
	int longopt_index = 0;
	int c;
	extern int optind, opterr;
	int show_usage = 0;
	char *optstring = "d:f:h";
	struct option long_options[] = {
		{ "help", 1, 0, 'h' },
		{ "duration", 1, 0, 'd' },
		{ "format", 1, 0, 'f' },
		{ 0, 0, 0, 0 }
	};

	while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) {
		switch (c) {
		case 1:
			// end of opts, but don't care
			break;
		case 'h':
			show_usage++;
			break;
		case 'd':
			duration = (float)atof(optarg);
			break;
		case 'f':
			if (*optarg == 'c' || *optarg == 'C') {
				c_format = 1;
			}
			break;
		default:
			show_usage++;
			break;
		}
	}
	if (show_usage || duration <= 0.0f) {
		fprintf(stderr, "usage: jack_impulse_grab -d duration [-f (C|gnuplot)]\n");
		exit(1);
	}

	/* try to become a client of the JACK server */

	if ((client = jack_client_open("impulse_grabber", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate. once the client is activated
	   (see below), you should rely on your own sample rate
	   callback (see above) for this value.
	*/

	fs = jack_get_sample_rate(client);
	response_duration = (unsigned long) (fs * duration);
	response = malloc(response_duration * sizeof(float));
	fprintf(stderr,
		"Grabbing %f seconds (%lu samples) of impulse response\n",
		duration, response_duration);

	/* create two ports */

	input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

	/* tell the JACK server that we are ready to roll */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	/* connect the ports. Note: you can't do this before
	   the client is activated (this may change in the future).
	*/

	if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) {
		fprintf(stderr, "Cannot find any physical capture ports");
		exit(1);
	}

	if (jack_connect (client, ports[0], jack_port_name (input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
	}

	free (ports);

	if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
		fprintf(stderr, "Cannot find any physical playback ports");
		exit(1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	free (ports);

	/* install a signal handler to properly quits jack client */
#ifdef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	/* Wait for grab to finish */
	while (!grab_finished) {
#ifdef WIN32
		Sleep(1000);
#else
		sleep (1);
#endif
	}
	jack_client_close (client);

	peak = response[0];
	peak_sample = 0;
	if (c_format) {
		printf("impulse[%lu] = {", response_duration);
		for (i=0; i<response_duration; i++) {
			if (i % 4 != 0) {
				printf(" ");
			} else {
				printf("\n\t");
			}
			printf("\"%+1.10f\"", response[i]);
			if (i < response_duration - 1) {
				printf(",");
			}
			if (fabs(response[i]) > peak) {
				peak = fabs(response[i]);
				peak_sample = i;
			}
		}
		printf("\n};\n");
	} else {
		for (i=0; i<response_duration; i++) {
			printf("%1.12f\n", response[i]);
			if (fabs(response[i]) > peak) {
				peak = fabs(response[i]);
				peak_sample = i;
			}
		}
	}
	fprintf(stderr, "Peak value was %f at sample %lu\n", peak, peak_sample);

	exit (0);
}
07070100000015000081A400000000000000000000000161E2F7EE00000D57000000000000000000000000000000000000003100000000jack-example-tools-1/example-clients/inprocess.c/** @file inprocess.c
 *
 * @brief This demonstrates the basic concepts for writing a client
 * that runs within the JACK server process.
 *
 * For the sake of example, a port_pair_t is allocated in
 * jack_initialize(), passed to inprocess() as an argument, then freed
 * in jack_finish().
 */

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <jack/jack.h>

/**
 * For the sake of example, an instance of this struct is allocated in
 * jack_initialize(), passed to inprocess() as an argument, then freed
 * in jack_finish().
 */
typedef struct {
	jack_port_t *input_port;
	jack_port_t *output_port;
} port_pair_t;

/**
 * Called in the realtime thread on every process cycle.  The entry
 * point name was passed to jack_set_process_callback() from
 * jack_initialize().  Although this is an internal client, its
 * process() interface is identical to @ref simple_client.c.
 *
 * @return 0 if successful; otherwise jack_finish() will be called and
 * the client terminated immediately.
 */
int
inprocess (jack_nframes_t nframes, void *arg)
{
	port_pair_t *pp = arg;
	jack_default_audio_sample_t *out =
		jack_port_get_buffer (pp->output_port, nframes);
	jack_default_audio_sample_t *in =
		jack_port_get_buffer (pp->input_port, nframes);

	memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);

	return 0;			/* continue */
}

/**
 * This required entry point is called after the client is loaded by
 * jack_internal_client_load().
 *
 * @param client pointer to JACK client structure.
 * @param load_init character string passed to the load operation.
 *
 * @return 0 if successful; otherwise jack_finish() will be called and
 * the client terminated immediately.
 */
JACK_LIB_EXPORT
int
jack_initialize (jack_client_t *client, const char *load_init)
{
	port_pair_t *pp = malloc (sizeof (port_pair_t));
	const char **ports;

	if (pp == NULL)
		return 1;		/* heap exhausted */

	jack_set_process_callback (client, inprocess, pp);

	/* create a pair of ports */
	pp->input_port = jack_port_register (client, "input",
					     JACK_DEFAULT_AUDIO_TYPE,
					     JackPortIsInput, 0);
	pp->output_port = jack_port_register (client, "output",
					      JACK_DEFAULT_AUDIO_TYPE,
					      JackPortIsOutput, 0);

	/* join the process() cycle */
	jack_activate (client);
	
	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		return 1;		/* terminate client */
	}

	if (jack_connect (client, ports[0], jack_port_name (pp->input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
	}
	
	jack_free (ports);
	
	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		return 1;		/* terminate client */
	}
	
	if (jack_connect (client, jack_port_name (pp->output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}
	
	jack_free (ports);

	return 0;			/* success */
}

/**
 * This required entry point is called immediately before the client
 * is unloaded, which could happen due to a call to
 * jack_internal_client_unload(), or a nonzero return from either
 * jack_initialize() or inprocess().
 *
 * @param arg the same parameter provided to inprocess().
 */
JACK_LIB_EXPORT
void
jack_finish (void *arg)
{
	if (arg)
		free ((port_pair_t *) arg);
}
07070100000016000081A400000000000000000000000161E2F7EE00001025000000000000000000000000000000000000003800000000jack-example-tools-1/example-clients/internal_metro.cpp/*
 Copyright (C) 2002 Anthony Van Groningen
 Copyright (C) 2005 Grame
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "internal_metro.h"

typedef jack_default_audio_sample_t sample_t;

const double PI = 3.14;

static int process_audio (jack_nframes_t nframes, void* arg)
{
    InternalMetro* metro = (InternalMetro*)arg;
    sample_t *buffer = (sample_t *) jack_port_get_buffer (metro->output_port, nframes);
    jack_nframes_t frames_left = nframes;

    while (metro->wave_length - metro->offset < frames_left) {
        memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * (metro->wave_length - metro->offset));
        frames_left -= metro->wave_length - metro->offset;
        metro->offset = 0;
    }
    if (frames_left > 0) {
        memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * frames_left);
        metro->offset += frames_left;
    }

    return 0;
}

InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, char* client_name)
{
    sample_t scale;
    int i, attack_length, decay_length;
    int attack_percent = 1, decay_percent = 10;
    const char *bpm_string = "bpm";

    offset = 0;

    /* Initial Jack setup, get sample rate */
    if (!client_name) {
        client_name = (char *) malloc (9 * sizeof (char));
        strcpy (client_name, "metro");
    }
    if ((client = jack_client_open (client_name, JackNullOption, NULL)) == 0) {
        fprintf (stderr, "jack server not running?\n");
        return;
    }

    jack_set_process_callback (client, process_audio, this);
    output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    input_port = jack_port_register (client, "metro_in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);

    sr = jack_get_sample_rate (client);

    /* setup wave table parameters */
    wave_length = 60 * sr / bpm;
    tone_length = sr * dur_arg / 1000;
    attack_length = tone_length * attack_percent / 100;
    decay_length = tone_length * decay_percent / 100;
    scale = 2 * PI * freq / sr;

    if (tone_length >= wave_length) {
        /*
        fprintf (stderr, "invalid duration (tone length = %" PRIu32
        	 ", wave length = %" PRIu32 "\n", tone_length,
        	 wave_length);
        */ 
        return;
    }
    if (attack_length + decay_length > (int)tone_length) {
        fprintf (stderr, "invalid attack/decay\n");
        return;
    }

    /* Build the wave table */
    wave = (sample_t *) malloc (wave_length * sizeof(sample_t));
    amp = (double *) malloc (tone_length * sizeof(double));

    for (i = 0; i < attack_length; i++) {
        amp[i] = max_amp * i / ((double) attack_length);
    }
    for (i = attack_length; i < (int) tone_length - decay_length; i++) {
        amp[i] = max_amp;
    }
    for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) {
        amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length);
    }
    for (i = 0; i < (int) tone_length; i++) {
        wave[i] = amp[i] * sin (scale * i);
    }
    for (i = tone_length; i < (int) wave_length; i++) {
        wave[i] = 0;
    }

    if (jack_activate (client)) {
        fprintf(stderr, "cannot activate client");
    }
}

InternalMetro::~InternalMetro()
{
    jack_deactivate(client);
    jack_port_unregister(client, input_port);
    jack_port_unregister(client, output_port);
    jack_client_close(client);
    free(amp);
    free(wave);
}
07070100000017000081A400000000000000000000000161E2F7EE00000658000000000000000000000000000000000000003600000000jack-example-tools-1/example-clients/internal_metro.h/*
 Copyright (C) 2001 Paul Davis
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with this program; if not, write to the Free Software 
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifndef __internal_metro__
#define __internal_metro__

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <getopt.h>
#include <string.h>

#include <jack/jack.h>
#include <jack/transport.h>


    typedef jack_default_audio_sample_t sample_t;

    /*!
    \brief A class to test internal clients
    */

    struct InternalMetro {

        jack_client_t *client;
        jack_port_t *input_port;
        jack_port_t *output_port;

        unsigned long sr;
        int freq;
        int bpm;
        jack_nframes_t tone_length, wave_length;
        sample_t *wave;
        double *amp;
        long offset ;

        InternalMetro(int freq, double max_amp, int dur_arg, int bpm, char* client_name);
        virtual ~InternalMetro();

    };

#ifdef __cplusplus
}
#endif

#endif
07070100000018000081A400000000000000000000000161E2F7EE00001359000000000000000000000000000000000000002E00000000jack-example-tools-1/example-clients/intime.c/*
 *  intime.c -- JACK internal timebase master example client.
 *
 *  To run: first start `jackd', then `jack_load intime intime 6/8,180bpm'.
 */

/*  Copyright (C) 2003 Jack O'Quin.
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <string.h>
#include <jack/jack.h>

/* Time and tempo variables, global to the entire transport timeline.
 * There is no attempt to keep a true tempo map.  The default time
 * signature is "march time": 4/4, 120bpm
 */
float time_beats_per_bar = 4.0;
float time_beat_type = 4.0;
double time_ticks_per_beat = 1920.0;
double time_beats_per_minute = 120.0;

/* BBT timebase callback.
 *
 * Runs in the process thread.  Realtime, must not wait.
 */
void 
timebbt (jack_transport_state_t state, jack_nframes_t nframes, 
	 jack_position_t *pos, int new_pos, void *arg)
{
	double min;			/* minutes since frame 0 */
	long abs_tick;			/* ticks since frame 0 */
	long abs_beat;			/* beats since frame 0 */

	if (new_pos) {

		pos->valid = JackPositionBBT;
		pos->beats_per_bar = time_beats_per_bar;
		pos->beat_type = time_beat_type;
		pos->ticks_per_beat = time_ticks_per_beat;
		pos->beats_per_minute = time_beats_per_minute;

		/* Compute BBT info from frame number.  This is
		 * relatively simple here, but would become complex if
		 * we supported tempo or time signature changes at
		 * specific locations in the transport timeline.  I
		 * make no claims for the numerical accuracy or
		 * efficiency of these calculations. */

		min = pos->frame / ((double) pos->frame_rate * 60.0);
		abs_tick = min * pos->beats_per_minute * pos->ticks_per_beat;
		abs_beat = abs_tick / pos->ticks_per_beat;

		pos->bar = abs_beat / pos->beats_per_bar;
		pos->beat = abs_beat - (pos->bar * pos->beats_per_bar) + 1;
		pos->tick = abs_tick - (abs_beat * pos->ticks_per_beat);
		pos->bar_start_tick = pos->bar * pos->beats_per_bar *
			pos->ticks_per_beat;
		pos->bar++;		/* adjust start to bar 1 */

		/* some debug code... */
		fprintf(stderr, "\nnew position: %" PRIu32 "\tBBT: %3"
			PRIi32 "|%" PRIi32 "|%04" PRIi32 "\n",
			pos->frame, pos->bar, pos->beat, pos->tick);

	} else {

		/* Compute BBT info based on previous period. */
		pos->tick += (nframes * pos->ticks_per_beat *
			      pos->beats_per_minute / (pos->frame_rate * 60));

		while (pos->tick >= pos->ticks_per_beat) {
			pos->tick -= pos->ticks_per_beat;
			if (++pos->beat > pos->beats_per_bar) {
				pos->beat = 1;
				++pos->bar;
				pos->bar_start_tick += (pos->beats_per_bar *
							pos->ticks_per_beat);
			}
		}
	}
}

/* experimental timecode callback
 *
 * Fill in extended timecode fields using the trivial assumption that
 * we are running at nominal speed, hence with no drift.
 *
 * It would probably be faster to compute frame_time without the
 * conditional expression.  But, this demonstrates the invariant:
 * next_time[i] == frame_time[i+1], unless a reposition occurs.
 *
 * Runs in the process thread.  Realtime, must not wait.
 */
void 
timecode (jack_transport_state_t state, jack_nframes_t nframes, 
	  jack_position_t *pos, int new_pos, void *arg)
{
	/* nominal transport speed */
	double seconds_per_frame = 1.0 / (double) pos->frame_rate;

	pos->valid = JackPositionTimecode;
	pos->frame_time = (new_pos?
			   pos->frame * seconds_per_frame:
			   pos->next_time);
	pos->next_time = (pos->frame + nframes) * seconds_per_frame;
}

/* after internal client loaded */
int
jack_initialize (jack_client_t *client, const char *load_init)
{
	JackTimebaseCallback callback = timebbt;

	int rc = sscanf(load_init, " %f/%f, %lf bpm ", &time_beats_per_bar,
			&time_beat_type, &time_beats_per_minute);

	if (rc > 0) {
		fprintf (stderr, "counting %.1f/%.1f at %.2f bpm\n",
			 time_beats_per_bar, time_beat_type,
			 time_beats_per_minute);
	} else {
		int len = strlen(load_init);
		if ((len > 0) && (strncmp(load_init, "timecode", len) == 0))
			callback = timecode;
	}

	if (jack_set_timebase_callback(client, 0, callback, NULL) != 0) {
		fprintf (stderr, "Unable to take over timebase.\n");
		return 1;		/* terminate */
	}

	fprintf (stderr, "Internal timebase master defined.\n");
	jack_activate (client);
	return 0;			/* success */
}

/* before unloading */
void
jack_finish (void *arg)
{
	fprintf (stderr, "Internal timebase client exiting.\n");
}
07070100000019000081A400000000000000000000000161E2F7EE000014F5000000000000000000000000000000000000003500000000jack-example-tools-1/example-clients/latent_client.c/** @file latent_client.c
 *
 * @brief This simple client demonstrates the most basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;
jack_client_t *client;

jack_default_audio_sample_t *delay_line;
jack_nframes_t delay_index;
jack_nframes_t latency = 1024;

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client does nothing more than copy data from its input
 * port to its output port. It will exit when stopped by
 * the user (e.g. using Ctrl-C on a unix-ish operating system)
 */
int
process (jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *in, *out;
	int k;

	in = jack_port_get_buffer (input_port, nframes);
	out = jack_port_get_buffer (output_port, nframes);

	for (k=0; k<nframes; k++) {
		out[k] = delay_line[delay_index];
		delay_line[delay_index] = in[k];
		delay_index = (delay_index + 1) % latency;
	}

	return 0;
}

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
	jack_latency_range_t range;
	if (mode == JackCaptureLatency) {
		jack_port_get_latency_range (input_port, mode, &range);
		range.min += latency;
		range.max += latency;
		jack_port_set_latency_range (output_port, mode, &range);
	} else {
		jack_port_get_latency_range (output_port, mode, &range);
		range.min += latency;
		range.max += latency;
		jack_port_set_latency_range (input_port, mode, &range);
	}
}

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown (void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name = "latent";
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;

	if (argc == 2)
		latency = atoi(argv[1]);

	delay_line = malloc( latency * sizeof(jack_default_audio_sample_t));
	if (delay_line == NULL) {
		fprintf (stderr, "no memory");
		exit(1);
	}

	memset (delay_line, 0, latency * sizeof(jack_default_audio_sample_t));

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `latency()' whenever
	   the latency needs to be recalculated.
	*/
	if (jack_set_latency_callback)
		jack_set_latency_callback (client, latency_cb, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate.
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_port = jack_port_register (client, "output",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}

	if (jack_connect (client, ports[0], jack_port_name (input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
		exit (1);
	}

	free (ports);

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	free (ports);

	/* keep running until stopped by the user */

#ifdef WIN32
	Sleep (-1);
#else
	sleep (-1);
#endif

	/* this is never reached but if the program
	   had some other way to exit besides being killed,
	   they would be important to call.
	*/

	jack_client_close (client);
	return 0;
}

0707010000001A000081A400000000000000000000000161E2F7EE00000E29000000000000000000000000000000000000003100000000jack-example-tools-1/example-clients/meson.buildexe_jack_control_client = executable(
  'jack_control_client',
  sources: ['control.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_cpu_load = executable(
  'jack_cpu_load',
  sources: ['cpu_load.c'],
  dependencies: [dep_jack],
  install: true
)

if build_jack_rec
  exe_jack_rec = executable(
    'jack_rec',
    sources: ['capture_client.c'],
    dependencies: [dep_jack, dep_sndfile, dep_threads],
    install: true
  )
endif

exe_jack_impulse_grabber = executable(
  'jack_impulse_grabber',
  sources: ['impulse_grabber.c'],
  dependencies: [dep_jack],
  install: true
)

lib_jack_inprocess = library(
  'jack_inprocess',
  name_prefix: '',
  sources: ['inprocess.c'],
  dependencies: [dep_jack],
  install: true,
  install_dir: get_option('libdir') / 'jack',
)

lib_jack_internal_metro = library(
  'jack_internal_metro',
  name_prefix: '',
  sources: ['internal_metro.cpp'],
  dependencies: [dep_jack],
  install: true,
  install_dir: get_option('libdir') / 'jack',
)

lib_jack_intime = library(
  'jack_intime',
  name_prefix: '',
  sources: ['intime.c'],
  dependencies: [dep_jack],
  install: true,
  install_dir: get_option('libdir') / 'jack',
)

exe_jack_latent_client = executable(
  'jack_latent_client',
  sources: ['latent_client.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_metro = executable(
  'jack_metro',
  sources: ['metro.c'],
  dependencies: [dep_jack, lib_m],
  install: true
)

exe_jack_midiseq = executable(
  'jack_midiseq',
  sources: ['midiseq.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_midisine = executable(
  'jack_midisine',
  sources: ['midisine.c'],
  dependencies: [dep_jack, lib_m],
  install: true
)

exe_jack_midi_latency_test = executable(
  'jack_midi_latency_test',
  sources: ['midi_latency_test.c'],
  dependencies: [dep_jack, dep_threads, lib_m],
  install: true
)

if build_jack_net
  exe_jack_net_master = executable(
    'jack_net_master',
    sources: ['netmaster.c'],
    dependencies: [lib_jacknet],
    install: true
  )

  exe_jack_net_slave = executable(
    'jack_net_slave',
    sources: ['netslave.c'],
    dependencies: [lib_jacknet],
    install: true
  )
endif

if has_jackctl_server_create2
  c_args_jack_server_control = c_args_common + ['-D__JACK2__']
else
  c_args_jack_server_control = c_args_common + ['-D__JACK1__']
endif
exe_jack_server_control = executable(
  'jack_server_control',
  c_args: c_args_jack_server_control,
  sources: ['server_control.c'],
  dependencies: [dep_jack, lib_jackserver],
  install: true
)

exe_jack_showtime = executable(
  'jack_showtime',
  sources: ['showtime.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_simdtests = executable(
  'jack_simdtests',
  sources: ['simdtests.cpp'],
  include_directories: ['../common'],
  dependencies: [lib_m],
  install: true
)

exe_jack_simple_client = executable(
  'jack_simple_client',
  sources: ['simple_client.c'],
  dependencies: [dep_jack, lib_m],
  install: true
)

# dont install, jack session is deprecated
exe_jack_simple_session_client = executable(
  'jack_simple_session_client',
  sources: ['simple_session_client.c'],
  dependencies: [dep_jack],
  c_args: ['-Wno-deprecated-declarations'],
  install: false
)

exe_jack_transport_client = executable(
  'jack_transport_client',
  sources: ['transport_client.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_thru_client = executable(
  'jack_thru_client',
  sources: ['thru_client.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_zombie = executable(
  'jack_zombie',
  sources: ['zombie.c'],
  dependencies: [dep_jack],
  install: true
)
0707010000001B000081A400000000000000000000000161E2F7EE00001E39000000000000000000000000000000000000002D00000000jack-example-tools-1/example-clients/metro.c/*
    Copyright (C) 2002 Anthony Van Groningen

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <math.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>

#include <jack/jack.h>
#include <jack/transport.h>

typedef jack_default_audio_sample_t sample_t;

const double PI = 3.14;

jack_client_t *client;
jack_port_t *output_port;
unsigned long sr;
int freq = 880;
int bpm;
jack_nframes_t tone_length, wave_length;
sample_t *wave;
long offset = 0;
int transport_aware = 0;
jack_transport_state_t transport_state;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void
usage ()
{
	fprintf (stderr, "\n"
"usage: jack_metro \n"
"              [ --frequency OR -f frequency (in Hz) ]\n"
"              [ --amplitude OR -A maximum amplitude (between 0 and 1) ]\n"
"              [ --duration OR -D duration (in ms) ]\n"
"              [ --attack OR -a attack (in percent of duration) ]\n"
"              [ --decay OR -d decay (in percent of duration) ]\n"
"              [ --name OR -n jack name for metronome client ]\n"
"              [ --transport OR -t transport aware ]\n"
"              --bpm OR -b beats per minute\n"
);
}

static void
process_silence (jack_nframes_t nframes)
{
	sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes);
	memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes);
}

jack_nframes_t last_time;
jack_time_t last_micro_time;

static void
process_audio (jack_nframes_t nframes)
{
	sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes);
	jack_nframes_t frames_left = nframes;

	while (wave_length - offset < frames_left) {
		memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset));
		frames_left -= wave_length - offset;
		offset = 0;
	}
	if (frames_left > 0) {
		memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left);
		offset += frames_left;
	}

	/*
	jack_nframes_t cur_time = jack_frame_time(client);
	jack_time_t cur_micro_time = jack_get_time();

	printf("jack_frame_time %lld micro %lld delta %d\n", cur_time, (cur_micro_time - last_micro_time), cur_time - last_time);
	last_time = cur_time;
	last_micro_time = cur_micro_time;
	*/
}

static int
process (jack_nframes_t nframes, void *arg)
{
	if (transport_aware) {
		jack_position_t pos;

		if (jack_transport_query (client, &pos)
		    != JackTransportRolling) {

			process_silence (nframes);
			return 0;
		}
		offset = pos.frame % wave_length;
	}
	process_audio (nframes);
	return 0;
}

int
main (int argc, char *argv[])
{
	sample_t scale;
	int i, attack_length, decay_length;
	double *amp;
	double max_amp = 0.5;
	int option_index;
	int opt;
	int got_bpm = 0;
	int attack_percent = 1, decay_percent = 10, dur_arg = 100;
	char *client_name = 0;
	char *bpm_string = "bpm";
	jack_status_t status;

	const char *options = "f:A:D:a:d:b:n:thv";
	struct option long_options[] =
	{
		{"frequency", 1, 0, 'f'},
		{"amplitude", 1, 0, 'A'},
		{"duration", 1, 0, 'D'},
		{"attack", 1, 0, 'a'},
		{"decay", 1, 0, 'd'},
		{"bpm", 1, 0, 'b'},
		{"name", 1, 0, 'n'},
		{"transport", 0, 0, 't'},
		{"help", 0, 0, 'h'},
		{"verbose", 0, 0, 'v'},
		{0, 0, 0, 0}
	};

	while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {
		switch (opt) {
		case 'f':
			if ((freq = atoi (optarg)) <= 0) {
				fprintf (stderr, "invalid frequency\n");
				return -1;
			}
			break;
		case 'A':
			if (((max_amp = atof (optarg)) <= 0)|| (max_amp > 1)) {
				fprintf (stderr, "invalid amplitude\n");
				return -1;
			}
			break;
		case 'D':
			dur_arg = atoi (optarg);
			fprintf (stderr, "durarg = %u\n", dur_arg);
			break;
		case 'a':
			if (((attack_percent = atoi (optarg)) < 0) || (attack_percent > 100)) {
				fprintf (stderr, "invalid attack percent\n");
				return -1;
			}
			break;
		case 'd':
			if (((decay_percent = atoi (optarg)) < 0) || (decay_percent > 100)) {
				fprintf (stderr, "invalid decay percent\n");
				return -1;
			}
			break;
		case 'b':
			got_bpm = 1;
			if ((bpm = atoi (optarg)) < 0) {
				fprintf (stderr, "invalid bpm\n");
				return -1;
			}
			bpm_string = (char *) malloc ((strlen (optarg) + 5) * sizeof (char));
			strcpy (bpm_string, optarg);
			strcat (bpm_string, "_bpm");
			break;
		case 'n':
			client_name = (char *) malloc ((strlen (optarg) + 1) * sizeof (char));
			strcpy (client_name, optarg);
			break;
		case 'v':
			break;
		case 't':
			transport_aware = 1;
			break;
		default:
			fprintf (stderr, "unknown option %c\n", opt);
		case 'h':
			usage ();
			return -1;
		}
	}
	if (!got_bpm) {
		fprintf (stderr, "bpm not specified\n");
		usage ();
		return -1;
	}

	/* Initial Jack setup, get sample rate */
	if (!client_name) {
		client_name = (char *) malloc (9 * sizeof (char));
		strcpy (client_name, "metro");
	}
	if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}
	jack_set_process_callback (client, process, 0);
	output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

	sr = jack_get_sample_rate (client);

	/* setup wave table parameters */
	wave_length = 60 * sr / bpm;
	tone_length = sr * dur_arg / 1000;
	attack_length = tone_length * attack_percent / 100;
	decay_length = tone_length * decay_percent / 100;
	scale = 2 * PI * freq / sr;

	if (tone_length >= wave_length) {
		fprintf (stderr, "invalid duration (tone length = %u, wave length = %u\n", tone_length, wave_length);
		return -1;
	}
	if (attack_length + decay_length > (int)tone_length) {
		fprintf (stderr, "invalid attack/decay\n");
		return -1;
	}

	/* Build the wave table */
	wave = (sample_t *) malloc (wave_length * sizeof(sample_t));
	amp = (double *) malloc (tone_length * sizeof(double));

	for (i = 0; i < attack_length; i++) {
		amp[i] = max_amp * i / ((double) attack_length);
	}
	for (i = attack_length; i < (int)tone_length - decay_length; i++) {
		amp[i] = max_amp;
	}
	for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) {
		amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length);
	}
	for (i = 0; i < (int)tone_length; i++) {
		wave[i] = amp[i] * sin (scale * i);
	}
	for (i = tone_length; i < (int)wave_length; i++) {
		wave[i] = 0;
	}

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client\n");
		goto error;
	}

	/* install a signal handler to properly quits jack client */
#ifdef WIN32
	signal(SIGINT, signal_handler);
	signal(SIGABRT, signal_handler);
	signal(SIGTERM, signal_handler);
#else
	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);
#endif

	/* run until interrupted */
	while (1) {
#ifdef WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	};

	jack_client_close(client);

error:
	free(amp);
	free(wave);
	exit (0);
}
0707010000001C000081A400000000000000000000000161E2F7EE000075C2000000000000000000000000000000000000003900000000jack-example-tools-1/example-clients/midi_latency_test.c/*
Copyright (C) 2010 Devin Anderson

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

/*
 * This program is used to measure MIDI latency and jitter.  It writes MIDI
 * messages to one port and calculates how long it takes before it reads the
 * same MIDI message over another port.  It was written to calculate the
 * latency and jitter of hardware and JACK hardware drivers, but might have
 * other practical applications.
 *
 * The latency results of the program include the latency introduced by the
 * JACK system.  Because JACK has sample accurate MIDI, the same latency
 * imposed on audio is also imposed on MIDI going through the system.  Make
 * sure you take this into account before complaining to me or (*especially*)
 * other JACK developers about reported MIDI latency.
 *
 * The jitter results are a little more interesting.  The program attempts to
 * calculate 'average jitter' and 'peak jitter', as defined here:
 *
 *     http://openmuse.org/transport/fidelity.html
 *
 * It also outputs a jitter plot, which gives you a more specific idea about
 * the MIDI jitter for the ports you're testing.  This is useful for catching
 * extreme jitter values, and for analyzing the amount of truth in the
 * technical specifications for your MIDI interface(s). :)
 *
 * This program is loosely based on 'alsa-midi-latency-test' in the ALSA test
 * suite.
 *
 * To port this program to non-POSIX platforms, you'll have to include
 * implementations for semaphores and command-line argument handling.
 */

#include <assert.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <getopt.h>

#include <jack/jack.h>
#include <jack/midiport.h>

#ifdef WIN32
#include <windows.h>
#include <unistd.h>
#else
#include <semaphore.h>
#endif

#define ABS(x) (((x) >= 0) ? (x) : (-(x)))

#ifdef WIN32
typedef HANDLE semaphore_t;
#else
typedef sem_t *semaphore_t;
#endif

const char *ERROR_MSG_TIMEOUT = "timed out while waiting for MIDI message";
const char *ERROR_RESERVE = "could not reserve MIDI event on port buffer";
const char *ERROR_SHUTDOWN = "the JACK server has been shutdown";

const char *SOURCE_EVENT_RESERVE = "jack_midi_event_reserve";
const char *SOURCE_PROCESS = "handle_process";
const char *SOURCE_SHUTDOWN = "handle_shutdown";
const char *SOURCE_SIGNAL_SEMAPHORE = "signal_semaphore";
const char *SOURCE_WAIT_SEMAPHORE = "wait_semaphore";

char *alias1;
char *alias2;
jack_client_t *client;
semaphore_t connect_semaphore;
volatile int connections_established;
const char *error_message;
const char *error_source;
jack_nframes_t highest_latency;
jack_time_t highest_latency_time;
jack_latency_range_t in_latency_range;
jack_port_t *in_port;
semaphore_t init_semaphore;
jack_nframes_t last_activity;
jack_time_t last_activity_time;
jack_time_t *latency_time_values;
jack_nframes_t *latency_values;
jack_nframes_t lowest_latency;
jack_time_t lowest_latency_time;
jack_midi_data_t *message_1;
jack_midi_data_t *message_2;
int messages_received;
int messages_sent;
size_t message_size;
jack_latency_range_t out_latency_range;
jack_port_t *out_port;
semaphore_t process_semaphore;
volatile sig_atomic_t process_state;
char *program_name;
jack_port_t *remote_in_port;
jack_port_t *remote_out_port;
size_t samples;
const char *target_in_port_name;
const char *target_out_port_name;
int timeout;
jack_nframes_t total_latency;
jack_time_t total_latency_time;
int unexpected_messages;
int xrun_count;

#ifdef WIN32
char semaphore_error_msg[1024];
#endif

static void
output_error(const char *source, const char *message);

static void
output_usage(void);

static void
set_process_error(const char *source, const char *message);

static int
signal_semaphore(semaphore_t semaphore);

static jack_port_t *
update_connection(jack_port_t *remote_port, int connected,
                  jack_port_t *local_port, jack_port_t *current_port,
                  const char *target_name);

static int
wait_semaphore(semaphore_t semaphore, int block);

static semaphore_t
create_semaphore(int id)
{
    semaphore_t semaphore;

#ifdef WIN32
    semaphore = CreateSemaphore(NULL, 0, 2, NULL);
#elif defined (__APPLE__)
    char name[128];
    sprintf(name, "midi_sem_%d", id);
    semaphore = sem_open(name, O_CREAT, 0777, 0);
    if (semaphore == (sem_t *) SEM_FAILED) {
        semaphore = NULL;
    }
#else
    semaphore = malloc(sizeof(semaphore_t));
    if (semaphore != NULL) {
        if (sem_init(semaphore, 0, 0)) {
            free(semaphore);
            semaphore = NULL;
        }
    }
#endif

    return semaphore;
}

static void
destroy_semaphore(semaphore_t semaphore, int id)
{

#ifdef WIN32
    CloseHandle(semaphore);
#else
    sem_destroy(semaphore);
#ifdef __APPLE__
    {
        char name[128];
        sprintf(name, "midi_sem_%d", id);
        sem_close(semaphore);
        sem_unlink(name);
    }
#else
    free(semaphore);
#endif
#endif

}

static void
die(const char *source, const char *error_message)
{
    output_error(source, error_message);
    output_usage();
    exit(EXIT_FAILURE);
}

static const char *
get_semaphore_error(void)
{

#ifdef WIN32
    DWORD error = GetLastError();
    if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                        semaphore_error_msg, 1024, NULL)) {
        snprintf(semaphore_error_msg, 1023, "Unknown OS error code '%ld'",
                error);
    }
    return semaphore_error_msg;
#else
    return strerror(errno);
#endif

}

static void
handle_info(const char *message)
{
    /* Suppress info */
}

static void
handle_port_connection_change(jack_port_id_t port_id_1,
                              jack_port_id_t port_id_2, int connected,
                              void *arg)
{
    jack_port_t *port_1;
    jack_port_t *port_2;
    if ((remote_in_port != NULL) && (remote_out_port != NULL)) {
        return;
    }
    port_1 = jack_port_by_id(client, port_id_1);
    port_2 = jack_port_by_id(client, port_id_2);

    /* The 'update_connection' call is not RT-safe.  It calls
       'jack_port_get_connections' and 'jack_free'.  This might be a problem
       with JACK 1, as this callback runs in the process thread in JACK 1. */

    if (port_1 == in_port) {
        remote_in_port = update_connection(port_2, connected, in_port,
                                           remote_in_port,
                                           target_in_port_name);
    } else if (port_2 == in_port) {
        remote_in_port = update_connection(port_1, connected, in_port,
                                           remote_in_port,
                                           target_in_port_name);
    } else if (port_1 == out_port) {
        remote_out_port = update_connection(port_2, connected, out_port,
                                            remote_out_port,
                                            target_out_port_name);
    } else if (port_2 == out_port) {
        remote_out_port = update_connection(port_1, connected, out_port,
                                            remote_out_port,
                                            target_out_port_name);
    }
    if ((remote_in_port != NULL) && (remote_out_port != NULL)) {
        connections_established = 1;
        if (! signal_semaphore(connect_semaphore)) {
            /* Sigh ... */
            die("post_semaphore", get_semaphore_error());
        }
        if (! signal_semaphore(init_semaphore)) {
            /* Sigh ... */
            die("post_semaphore", get_semaphore_error());
        }
    }
}

static int
handle_process(jack_nframes_t frames, void *arg)
{
    jack_midi_data_t *buffer;
    jack_midi_event_t event;
    jack_nframes_t event_count;
    jack_nframes_t event_time;
    jack_nframes_t frame;
    size_t i;
    jack_nframes_t last_frame_time;
    jack_midi_data_t *message;
    jack_time_t microseconds;
    void *port_buffer;
    jack_time_t time;
    jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames));
    switch (process_state) {

    case 0:
        /* State: initializing */
        switch (wait_semaphore(init_semaphore, 0)) {
        case -1:
            set_process_error(SOURCE_WAIT_SEMAPHORE, get_semaphore_error());
            /* Fallthrough on purpose */
        case 0:
            return 0;
        }
        highest_latency = 0;
        lowest_latency = 0;
        messages_received = 0;
        messages_sent = 0;
        process_state = 1;
        total_latency = 0;
        total_latency_time = 0;
        unexpected_messages = 0;
        xrun_count = 0;
        jack_port_get_latency_range(remote_in_port, JackCaptureLatency,
                                    &in_latency_range);
        jack_port_get_latency_range(remote_out_port, JackPlaybackLatency,
                                    &out_latency_range);
        goto send_message;

    case 1:
        /* State: processing */
        port_buffer = jack_port_get_buffer(in_port, frames);
        event_count = jack_midi_get_event_count(port_buffer);
        last_frame_time = jack_last_frame_time(client);
        for (i = 0; i < event_count; i++) {
            jack_midi_event_get(&event, port_buffer, i);
            message = (messages_received % 2) ? message_2 : message_1;
            if ((event.size == message_size) &&
                (! memcmp(message, event.buffer,
                          message_size * sizeof(jack_midi_data_t)))) {
                goto found_message;
            }
            unexpected_messages++;
        }
        microseconds = jack_frames_to_time(client, last_frame_time) -
            last_activity_time;
        if ((microseconds / 1000000) >= timeout) {
            set_process_error(SOURCE_PROCESS, ERROR_MSG_TIMEOUT);
        }
        break;
    found_message:
        event_time = last_frame_time + event.time;
        frame = event_time - last_activity;
        time = jack_frames_to_time(client, event_time) - last_activity_time;
        if ((! highest_latency) || (frame > highest_latency)) {
            highest_latency = frame;
            highest_latency_time = time;
        }
        if ((! lowest_latency) || (frame < lowest_latency)) {
            lowest_latency = frame;
            lowest_latency_time = time;
        }
        latency_time_values[messages_received] = time;
        latency_values[messages_received] = frame;
        total_latency += frame;
        total_latency_time += time;
        messages_received++;
        if (messages_received == samples) {
            process_state = 2;
            if (! signal_semaphore(process_semaphore)) {
                /* Sigh ... */
                die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error());
            }
            break;
        }
    send_message:
        frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames);
        if (frame >= frames) {
            frame = frames - 1;
        }
        port_buffer = jack_port_get_buffer(out_port, frames);
        buffer = jack_midi_event_reserve(port_buffer, frame, message_size);
        if (buffer == NULL) {
            set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE);
            break;
        }
        message = (messages_sent % 2) ? message_2 : message_1;
        memcpy(buffer, message, message_size * sizeof(jack_midi_data_t));
        last_activity = jack_last_frame_time(client) + frame;
        last_activity_time = jack_frames_to_time(client, last_activity);
        messages_sent++;

    case 2:
        /* State: finished - do nothing */
    case -1:
        /* State: error - do nothing */
    case -2:
        /* State: signalled - do nothing */
        ;
    }
    return 0;
}

static void
handle_shutdown(void *arg)
{
    set_process_error(SOURCE_SHUTDOWN, ERROR_SHUTDOWN);
}

static void
handle_signal(int sig)
{
    process_state = -2;
    if (! signal_semaphore(connect_semaphore)) {
        /* Sigh ... */
        die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error());
    }
    if (! signal_semaphore(process_semaphore)) {
        /* Sigh ... */
        die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error());
    }
}

static int
handle_xrun(void *arg)
{
    xrun_count++;
    return 0;
}

static void
output_error(const char *source, const char *message)
{
    fprintf(stderr, "%s: %s: %s\n", program_name, source, message);
}

static void
output_usage(void)
{
    fprintf(stderr, "Usage: %s [options] [out-port-name in-port-name]\n\n"
            "\t-h, --help              print program usage\n"
            "\t-m, --message-size=size set size of MIDI messages to send "
            "(default: 3)\n"
            "\t-s, --samples=n         number of MIDI messages to send "
            "(default: 1024)\n"
            "\t-t, --timeout=seconds   message timeout (default: 5)\n\n",
            program_name);
}

static unsigned long
parse_positive_number_arg(char *s, char *name)
{
    char *end_ptr;
    unsigned long result;
    errno = 0;
    result = strtoul(s, &end_ptr, 10);
    if (errno) {
        die(name, strerror(errno));
    }
    if (*s == '\0') {
        die(name, "argument value cannot be empty");
    }
    if (*end_ptr != '\0') {
        die(name, "invalid value");
    }
    if (! result) {
        die(name, "must be a positive number");
    }
    return result;
}

static int
register_signal_handler(void (*func)(int))
{

#ifdef WIN32
    if (signal(SIGABRT, func) == SIG_ERR) {
        return 0;
    }
#else
    if (signal(SIGQUIT, func) == SIG_ERR) {
        return 0;
    }
    if (signal(SIGHUP, func) == SIG_ERR) {
        return 0;
    }
#endif

    if (signal(SIGINT, func) == SIG_ERR) {
        return 0;
    }
    if (signal(SIGTERM, func) == SIG_ERR) {
        return 0;
    }
    return 1;
}

static void
set_process_error(const char *source, const char *message)
{
    error_source = source;
    error_message = message;
    process_state = -1;
    if (! signal_semaphore(process_semaphore)) {
        /* Sigh ... */
        output_error(source, message);
        die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error());
    }
}

static int
signal_semaphore(semaphore_t semaphore)
{

#ifdef WIN32
    return ReleaseSemaphore(semaphore, 1, NULL);
#else
    return ! sem_post(semaphore);
#endif

}

static jack_port_t *
update_connection(jack_port_t *remote_port, int connected,
                  jack_port_t *local_port, jack_port_t *current_port,
                  const char *target_name)
{
    if (connected) {
        if (current_port) {
            return current_port;
        }
        if (target_name) {
            char *aliases[2];
            if (! strcmp(target_name, jack_port_name(remote_port))) {
                return remote_port;
            }
            aliases[0] = alias1;
            aliases[1] = alias2;
            switch (jack_port_get_aliases(remote_port, aliases)) {
            case -1:
                /* Sigh ... */
                die("jack_port_get_aliases", "Failed to get port aliases");
            case 2:
                if (! strcmp(target_name, alias2)) {
                    return remote_port;
                }
                /* Fallthrough on purpose */
            case 1:
                if (! strcmp(target_name, alias1)) {
                    return remote_port;
                }
                /* Fallthrough on purpose */
            case 0:
                return NULL;
            }
            /* This shouldn't happen. */
            assert(0);
        }
        return remote_port;
    }
    if (! strcmp(jack_port_name(remote_port), jack_port_name(current_port))) {
        const char **port_names;
        if (target_name) {
            return NULL;
        }
        port_names = jack_port_get_connections(local_port);
        if (port_names == NULL) {
            return NULL;
        }

        /* If a connected port is disconnected and other ports are still
           connected, then we take the first port name in the array and use it
           as our remote port.  It's a dumb implementation. */
        current_port = jack_port_by_name(client, port_names[0]);
        jack_free(port_names);
        if (current_port == NULL) {
            /* Sigh */
            die("jack_port_by_name", "failed to get port by name");
        }
    }
    return current_port;
}

static int
wait_semaphore(semaphore_t semaphore, int block)
{

#ifdef WIN32
    DWORD result = WaitForSingleObject(semaphore, block ? INFINITE : 0);
    switch (result) {
    case WAIT_OBJECT_0:
        return 1;
    case WAIT_TIMEOUT:
        return 0;
    }
    return -1;
#else
    if (block) {
        while (sem_wait(semaphore)) {
            if (errno != EINTR) {
                return -1;
            }
        }
    } else {
        while (sem_trywait(semaphore)) {
            switch (errno) {
            case EAGAIN:
                return 0;
            case EINTR:
                continue;
            default:
                return -1;
            }
        }
    }
    return 1;
#endif

}

int
main(int argc, char **argv)
{
    int jitter_plot[101];
    int latency_plot[101];
    int long_index = 0;
    struct option long_options[] = {
        {"help", 0, NULL, 'h'},
        {"message-size", 1, NULL, 'm'},
        {"samples", 1, NULL, 's'},
        {"timeout", 1, NULL, 't'}
    };
    size_t name_arg_count;
    size_t name_size;
    char *option_string = "hm:s:t:";
    int show_usage = 0;
    connections_established = 0;
    error_message = NULL;
    message_size = 3;
    program_name = argv[0];
    remote_in_port = 0;
    remote_out_port = 0;
    samples = 1024;
    timeout = 5;

    for (;;) {
        signed char c = getopt_long(argc, argv, option_string, long_options,
                             &long_index);
        switch (c) {
        case 'h':
            show_usage = 1;
            break;
        case 'm':
            message_size = parse_positive_number_arg(optarg, "message-size");
            break;
        case 's':
            samples = parse_positive_number_arg(optarg, "samples");
            break;
        case 't':
            timeout = parse_positive_number_arg(optarg, "timeout");
            break;
        default:
            {
                char *s = "'- '";
                s[2] = c;
                die(s, "invalid switch");
            }
        case -1:
            if (show_usage) {
                output_usage();
                exit(EXIT_SUCCESS);
            }
            goto parse_port_names;
        case 1:
            /* end of switch :) */
            ;
        }
    }
 parse_port_names:
    name_arg_count = argc - optind;
    switch (name_arg_count) {
    case 2:
        target_in_port_name = argv[optind + 1];
        target_out_port_name = argv[optind];
        break;
    case 0:
        target_in_port_name = 0;
        target_out_port_name = 0;
        break;
    default:
        output_usage();
        return EXIT_FAILURE;
    }
    name_size = jack_port_name_size();
    alias1 = malloc(name_size * sizeof(char));
    if (alias1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto show_error;
    }
    alias2 = malloc(name_size * sizeof(char));
    if (alias2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias1;
    }
    latency_values = malloc(sizeof(jack_nframes_t) * samples);
    if (latency_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias2;
    }
    latency_time_values = malloc(sizeof(jack_time_t) * samples);
    if (latency_time_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_values;
    }
    message_1 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_time_values;
    }
    message_2 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_message_1;
    }
    switch (message_size) {
    case 1:
        message_1[0] = 0xf6;
        message_2[0] = 0xfe;
        break;
    case 2:
        message_1[0] = 0xc0;
        message_1[1] = 0x00;
        message_2[0] = 0xd0;
        message_2[1] = 0x7f;
        break;
    case 3:
        message_1[0] = 0x80;
        message_1[1] = 0x00;
        message_1[2] = 0x00;
        message_2[0] = 0x90;
        message_2[1] = 0x7f;
        message_2[2] = 0x7f;
        break;
    default:
        message_1[0] = 0xf0;
        memset(message_1 + 1, 0,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_1[message_size - 1] = 0xf7;
        message_2[0] = 0xf0;
        memset(message_2 + 1, 0x7f,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_2[message_size - 1] = 0xf7;
    }
    client = jack_client_open(program_name, JackNullOption, NULL);
    if (client == NULL) {
        error_message = "failed to open JACK client";
        error_source = "jack_client_open";
        goto free_message_2;
    }
    in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE,
                                 JackPortIsInput, 0);
    if (in_port == NULL) {
        error_message = "failed to register MIDI-in port";
        error_source = "jack_port_register";
        goto close_client;
    }
    out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE,
                                  JackPortIsOutput, 0);
    if (out_port == NULL) {
        error_message = "failed to register MIDI-out port";
        error_source = "jack_port_register";
        goto unregister_in_port;
    }
    if (jack_set_process_callback(client, handle_process, NULL)) {
        error_message = "failed to set process callback";
        error_source = "jack_set_process_callback";
        goto unregister_out_port;
    }
    if (jack_set_xrun_callback(client, handle_xrun, NULL)) {
        error_message = "failed to set xrun callback";
        error_source = "jack_set_xrun_callback";
        goto unregister_out_port;
    }
    if (jack_set_port_connect_callback(client, handle_port_connection_change,
                                       NULL)) {
        error_message = "failed to set port connection callback";
        error_source = "jack_set_port_connect_callback";
        goto unregister_out_port;
    }
    jack_on_shutdown(client, handle_shutdown, NULL);
    jack_set_info_function(handle_info);
    process_state = 0;

    connect_semaphore = create_semaphore(0);
    if (connect_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto unregister_out_port;
    }
    init_semaphore = create_semaphore(1);
    if (init_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_connect_semaphore;
    }
    process_semaphore = create_semaphore(2);
    if (process_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_init_semaphore;
    }
    if (jack_activate(client)) {
        error_message = "could not activate client";
        error_source = "jack_activate";
        goto destroy_process_semaphore;
    }
    if (name_arg_count) {
        if (jack_connect(client, jack_port_name(out_port),
                         target_out_port_name)) {
            error_message = "could not connect MIDI out port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
        if (jack_connect(client, target_in_port_name,
                         jack_port_name(in_port))) {
            error_message = "could not connect MIDI in port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(handle_signal)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    printf("Waiting for connections ...\n");
    if (wait_semaphore(connect_semaphore, 1) == -1) {
        error_message = get_semaphore_error();
        error_source = "wait_semaphore";
        goto deactivate_client;
    }
    if (connections_established) {
        printf("Waiting for test completion ...\n\n");
        if (wait_semaphore(process_semaphore, 1) == -1) {
            error_message = get_semaphore_error();
            error_source = "wait_semaphore";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(SIG_DFL)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    if (process_state == 2) {
        double average_latency = ((double) total_latency) / samples;
        double average_latency_time = total_latency_time / samples;
        size_t i;
        double latency_plot_offset =
            floor(((double) lowest_latency_time) / 100.0) / 10.0;
        double sample_rate = (double) jack_get_sample_rate(client);
        jack_nframes_t total_jitter = 0;
        jack_time_t total_jitter_time = 0;
        for (i = 0; i <= 100; i++) {
            jitter_plot[i] = 0;
            latency_plot[i] = 0;
        }
        for (i = 0; i < samples; i++) {
            double latency_time_value = (double) latency_time_values[i];
            double latency_plot_time =
                (latency_time_value / 1000.0) - latency_plot_offset;
            double jitter_time = ABS(average_latency_time -
                                     latency_time_value);
            if (latency_plot_time >= 10.0) {
                (latency_plot[100])++;
            } else {
                (latency_plot[(int) (latency_plot_time * 10.0)])++;
            }
            if (jitter_time >= 10000.0) {
                (jitter_plot[100])++;
            } else {
                (jitter_plot[(int) (jitter_time / 100.0)])++;
            }
            total_jitter += ABS(average_latency -
                                ((double) latency_values[i]));
            total_jitter_time += jitter_time;
        }
        printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Average latency: %.2f ms (%.2f frames)\n"
               "Lowest latency: %.2f ms (%u frames)\n"
               "Highest latency: %.2f ms (%u frames)\n"
               "Peak MIDI jitter: %.2f ms (%u frames)\n"
               "Average MIDI jitter: %.2f ms (%.2f frames)\n",
               (out_latency_range.min / sample_rate) * 1000.0,
               (out_latency_range.max / sample_rate) * 1000.0,
               out_latency_range.min, out_latency_range.max,
               (in_latency_range.min / sample_rate) * 1000.0,
               (in_latency_range.max / sample_rate) * 1000.0,
               in_latency_range.min, in_latency_range.max,
               average_latency_time / 1000.0, average_latency,
               lowest_latency_time / 1000.0, lowest_latency,
               highest_latency_time / 1000.0, highest_latency,
               (highest_latency_time - lowest_latency_time) / 1000.0,
               highest_latency - lowest_latency,
               (total_jitter_time / 1000.0) / samples,
               ((double) total_jitter) / samples);
        printf("\nJitter Plot:\n");
        for (i = 0; i < 100; i++) {
            if (jitter_plot[i]) {
                printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0,
                       ((float) (i + 1)) / 10.0, jitter_plot[i]);
            }
        }
        if (jitter_plot[100]) {
            printf("     > 10 ms: %d\n", jitter_plot[100]);
        }
        printf("\nLatency Plot:\n");
        for (i = 0; i < 100; i++) {
            if (latency_plot[i]) {
                printf("%.1f - %.1f ms: %d\n",
                       latency_plot_offset + (((float) i) / 10.0),
                       latency_plot_offset + (((float) (i + 1)) / 10.0),
                       latency_plot[i]);
            }
        }
        if (latency_plot[100]) {
            printf("     > %.1f ms: %d\n", latency_plot_offset + 10.0,
                   latency_plot[100]);
        }
    }
 deactivate_client:
    jack_deactivate(client);
    printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent,
           messages_received);
    if (unexpected_messages) {
        printf("Unexpected messages received: %d\n", unexpected_messages);
    }
    if (xrun_count) {
        printf("Xruns: %d\n", xrun_count);
    }
 destroy_process_semaphore:
    destroy_semaphore(process_semaphore, 2);
 destroy_init_semaphore:
    destroy_semaphore(init_semaphore, 1);
 destroy_connect_semaphore:
    destroy_semaphore(connect_semaphore, 0);
 unregister_out_port:
    jack_port_unregister(client, out_port);
 unregister_in_port:
    jack_port_unregister(client, in_port);
 close_client:
    jack_client_close(client);
 free_message_2:
    free(message_2);
 free_message_1:
    free(message_1);
 free_latency_time_values:
    free(latency_time_values);
 free_latency_values:
    free(latency_values);
 free_alias2:
    free(alias2);
 free_alias1:
    free(alias1);
    if (error_message != NULL) {
    show_error:
        output_error(error_source, error_message);
        exit(EXIT_FAILURE);
    }
    return EXIT_SUCCESS;
}
0707010000001D000081A400000000000000000000000161E2F7EE00000F79000000000000000000000000000000000000002F00000000jack-example-tools-1/example-clients/midiseq.c/*
    Copyright (C) 2004 Ian Esten

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <jack/jack.h>
#include <jack/midiport.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

jack_client_t *client;
jack_port_t *output_port;

unsigned char* note_frqs;
jack_nframes_t* note_starts;
jack_nframes_t* note_lengths;
jack_nframes_t num_notes;
jack_nframes_t loop_nsamp;
jack_nframes_t loop_index;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void usage()
{
	fprintf(stderr, "usage: jack_midiseq name nsamp [startindex note nsamp] ...... [startindex note nsamp]\n");
	fprintf(stderr, "eg: jack_midiseq Sequencer 24000 0 60 8000 12000 63 8000\n");
	fprintf(stderr, "will play a 1/2 sec loop (if srate is 48khz) with a c4 note at the start of the loop\n");
	fprintf(stderr, "that lasts for 12000 samples, then a d4# that starts at 1/4 sec that lasts for 800 samples\n");
}

static int process(jack_nframes_t nframes, void *arg)
{
	int i,j;
	void* port_buf = jack_port_get_buffer(output_port, nframes);
	unsigned char* buffer;
	jack_midi_clear_buffer(port_buf);
	/*memset(buffer, 0, nframes*sizeof(jack_default_audio_sample_t));*/

	for (i = 0; i < nframes; i++) {
		for (j = 0; j < num_notes; j++) {
			if (note_starts[j] == loop_index) {
				if ((buffer = jack_midi_event_reserve(port_buf, i, 3))) {
					/* printf("wrote a note on, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer); */
					buffer[2] = 64;		/* velocity */
					buffer[1] = note_frqs[j];
					buffer[0] = 0x90;	/* note on */
				}
			} else if (note_starts[j] + note_lengths[j] == loop_index) {
				if ((buffer = jack_midi_event_reserve(port_buf, i, 3))) {
					/* printf("wrote a note off, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer); */
					buffer[2] = 64;		/* velocity */
					buffer[1] = note_frqs[j];
					buffer[0] = 0x80;	/* note off */
				}
			}
		}
		loop_index = loop_index+1 >= loop_nsamp ? 0 : loop_index+1;
	}
	return 0;
}

int main(int narg, char **args)
{
	int i;
	if ((narg<6) || ((narg-3)%3 != 0)) {
		usage();
		exit(1);
	}
	if ((client = jack_client_open (args[1], JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}
	jack_set_process_callback (client, process, 0);
	output_port = jack_port_register (client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);

	loop_index = 0;
	num_notes = (narg - 3)/3;
	note_frqs = malloc(num_notes*sizeof(unsigned char));
	note_starts = malloc(num_notes*sizeof(jack_nframes_t));
	note_lengths = malloc(num_notes*sizeof(jack_nframes_t));
	loop_nsamp = atoi(args[2]);
	for (i = 0; i < num_notes; i++) {
		note_starts[i] = atoi(args[3 + 3*i]);
		note_frqs[i] = atoi(args[4 + 3*i]);
		note_lengths[i] = atoi(args[5 + 3*i]);
	}

	if (jack_activate(client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	/* install a signal handler to properly quits jack client */
#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	/* run until interrupted */
	while (1) {
#ifdef WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	};

	jack_client_close(client);
	exit (0);
}
0707010000001E000081A400000000000000000000000161E2F7EE000010C1000000000000000000000000000000000000003000000000jack-example-tools-1/example-clients/midisine.c/*
    Copyright (C) 2004 Ian Esten

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#include <inttypes.h>

#include <jack/jack.h>
#include <jack/midiport.h>

jack_port_t *input_port;
jack_port_t *output_port;
jack_default_audio_sample_t ramp=0.0;
jack_default_audio_sample_t note_on;
unsigned char note = 0;
jack_default_audio_sample_t note_frqs[128];

jack_client_t *client;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void calc_note_frqs(jack_default_audio_sample_t srate)
{
	int i;
	for(i=0; i<128; i++)
	{
		note_frqs[i] = (2.0 * 440.0 / 32.0) * pow(2, (((jack_default_audio_sample_t)i - 9.0) / 12.0)) / srate;
	}
}

static int process(jack_nframes_t nframes, void *arg)
{
	int i;
	void* port_buf = jack_port_get_buffer(input_port, nframes);
	jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
	jack_midi_event_t in_event;
	jack_nframes_t event_index = 0;
	jack_nframes_t event_count = jack_midi_get_event_count(port_buf);
	if(event_count > 1)
	{
		printf(" midisine: have %d events\n", event_count);
		for(i=0; i<event_count; i++)
		{
			jack_midi_event_get(&in_event, port_buf, i);
			printf("    event %d time is %d. 1st byte is 0x%x\n", i, in_event.time, *(in_event.buffer));
		}
/*		printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/
	}
	jack_midi_event_get(&in_event, port_buf, 0);
	for(i = 0; i < nframes; i++)
	{
		if ((in_event.time == i) && (event_index < event_count))
		{
			if (((*(in_event.buffer) & 0xf0)) == 0x90)
			{
				/* note on */
				note = *(in_event.buffer + 1);
				if (*(in_event.buffer + 2) == 0) {
					note_on = 0.0;
				} else {
					note_on = (float)(*(in_event.buffer + 2)) / 127.f;
				}
			}
			else if (((*(in_event.buffer)) & 0xf0) == 0x80)
			{
				/* note off */
				note = *(in_event.buffer + 1);
				note_on = 0.0;
			}
			event_index++;
			if(event_index < event_count)
				jack_midi_event_get(&in_event, port_buf, event_index);
		}
		ramp += note_frqs[note];
		ramp = (ramp > 1.0) ? ramp - 2.0 : ramp;
		out[i] = note_on*sin(2*M_PI*ramp);
	}
	return 0;
}

static int srate(jack_nframes_t nframes, void *arg)
{
	printf("the sample rate is now %" PRIu32 "/sec\n", nframes);
	calc_note_frqs((jack_default_audio_sample_t)nframes);
	return 0;
}

static void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

int main(int narg, char **args)
{
	if ((client = jack_client_open("midisine", JackNullOption, NULL)) == 0)
	{
		fprintf(stderr, "JACK server not running?\n");
		return 1;
	}

	calc_note_frqs(jack_get_sample_rate (client));

	jack_set_process_callback (client, process, 0);

	jack_set_sample_rate_callback (client, srate, 0);

	jack_on_shutdown (client, jack_shutdown, 0);

	input_port = jack_port_register (client, "midi_in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
	output_port = jack_port_register (client, "audio_out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

	if (jack_activate (client))
	{
		fprintf(stderr, "cannot activate client");
		return 1;
	}

	/* install a signal handler to properly quits jack client */
#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	/* run until interrupted */
	while(1) {
#ifdef WIN32
		Sleep(1*1000);
#else
		sleep(1);
#endif
	}
	jack_client_close(client);
	exit (0);
}

0707010000001F000081A400000000000000000000000161E2F7EE0000160C000000000000000000000000000000000000003100000000jack-example-tools-1/example-clients/netmaster.c/*
    Copyright (C) 2009 Grame

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <math.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>

#include <jack/net.h>

jack_net_master_t* net;

#define BUFFER_SIZE 512
#define SAMPLE_RATE 44100

static void signal_handler(int sig)
{
	jack_net_master_close(net);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void
usage ()
{
	fprintf (stderr, "\n"
    "usage: jack_net_master \n"
    "              [ -b buffer size (default = %d) ]\n"
    "              [ -r sample rate (default = %d) ]\n"
    "              [ -a hostname (default = %s) ]\n"
    "              [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT);
}

int
main (int argc, char *argv[])
{
    int buffer_size = BUFFER_SIZE;
    int sample_rate = SAMPLE_RATE;
    int udp_port = DEFAULT_PORT;
    const char* multicast_ip = DEFAULT_MULTICAST_IP;
 	const char *options = "b:r:a:p:h";
    int option_index;
	int opt;

    struct option long_options[] =
	{
		{"buffer size", 1, 0, 'b'},
		{"sample rate", 1, 0, 'r'},
		{"hostname", 1, 0, 'a'},
		{"port", 1, 0, 'p'},
		{0, 0, 0, 0}
	};

	while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {

		switch (opt) {

		case 'b':
			buffer_size = atoi(optarg);
			break;

		case 'r':
			sample_rate = atoi(optarg);
			break;

		case 'a':
            multicast_ip = strdup(optarg);
            break;

		case 'p':
			udp_port = atoi(optarg);
			break;

		case 'h':
			usage();
			return -1;
		}
	}

    int i;
    //jack_master_t request = { 4, 4, -1, -1, buffer_size, sample_rate, "master", -1 };
    jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "net_master", 6, true };
    jack_slave_t result;
    float** audio_input_buffer;
    float** audio_output_buffer;
    int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate));

    printf("Waiting for a slave...\n");

    if ((net = jack_net_master_open(multicast_ip, udp_port, &request, &result))  == 0) {
        fprintf(stderr, "NetJack master can not be opened\n");
		return 1;
	}

    printf("Slave is running...\n");

    /* install a signal handler to properly quits jack client */
#ifdef WIN32
	signal(SIGINT, signal_handler);
    signal(SIGABRT, signal_handler);
	signal(SIGTERM, signal_handler);
#else
	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);
#endif

    // Allocate buffers
    
    audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*));
    for (i = 0; i < result.audio_input; i++) {
        audio_input_buffer[i] = (float*)calloc(buffer_size, sizeof(float));
    }

    audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*));
    for (i = 0; i < result.audio_output; i++) {
        audio_output_buffer[i] = (float*)calloc(buffer_size, sizeof(float));
    }

    /*
    Run until interrupted.

    WARNING !! : this code is given for demonstration purpose. For proper timing bevahiour
    it has to be called in a real-time context (which is *not* the case here...)
    */
    
    //usleep(5*1000000);
    printf("Wait...\n");
    //sleep(10);
    usleep(1000000);
    printf("Wait...OK\n");
  
  	while (1) {

        // Copy input to output
        assert(result.audio_input == result.audio_output);
        for (i = 0; i < result.audio_input; i++) {
            memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float));
        }
   
        /*
        if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) {
            printf("jack_net_master_send failure, exiting\n");
            break;
        }
        
        usleep(10000);
         
        if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) {
            printf("jack_net_master_recv failure, exiting\n");
            break;
        }
        */
        
        if (jack_net_master_send_slice(net, result.audio_output, audio_output_buffer, 0, NULL, BUFFER_SIZE/2) < 0) {
            printf("jack_net_master_send failure, exiting\n");
            break;
        }
        
        usleep(10000);
         
        if (jack_net_master_recv_slice(net, result.audio_input, audio_input_buffer, 0, NULL, BUFFER_SIZE/2) < 0) {
            printf("jack_net_master_recv failure, exiting\n");
            break;
        }
        
        usleep(wait_usec);
	};

    // Wait for application end
    jack_net_master_close(net);

    for (i = 0; i < result.audio_input; i++) {
        free(audio_input_buffer[i]);
    }
    free(audio_input_buffer);

    for (i = 0; i < result.audio_output; i++) {
          free(audio_output_buffer[i]);
    }
    free(audio_output_buffer);

    exit (0);
}
07070100000020000081A400000000000000000000000161E2F7EE0000103D000000000000000000000000000000000000003000000000jack-example-tools-1/example-clients/netslave.c/*
    Copyright (C) 2009 Grame

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <math.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>

#include <jack/net.h>

jack_net_slave_t* net;

static void signal_handler(int sig)
{
	jack_net_slave_close(net);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void
usage ()
{
	fprintf (stderr, "\n"
    "usage: jack_net_slave \n"
    "              [ -C capture channels (default = 2)]\n"
    "              [ -P playback channels (default = 2) ]\n"
    "              [ -a hostname (default = %s) ]\n"
    "              [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT);
}

static void net_shutdown(void* data)
{
    printf("Restarting...\n");
}

static int net_process(jack_nframes_t buffer_size,
                        int audio_input,
                        float** audio_input_buffer,
                        int midi_input,
                        void** midi_input_buffer,
                        int audio_output,
                        float** audio_output_buffer,
                        int midi_output,
                        void** midi_output_buffer,
                        void* data)
{
    int i;

    // Copy input to output
    for (i = 0; i < audio_input; i++) {
        memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float));
    }
    return 0;
}

int
main (int argc, char *argv[])
{
    int audio_input = 2;
    int audio_output = 2;
    int udp_port = DEFAULT_PORT;
    const char* multicast_ip = DEFAULT_MULTICAST_IP;
    const char *options = "C:P:a:p:h";
    int option_index;
    int opt;

	struct option long_options[] =
	{
		{"audio input", 1, 0, 'C'},
		{"audio output", 1, 0, 'P'},
		{"hostname", 1, 0, 'a'},
		{"port", 1, 0, 'p'},
		{0, 0, 0, 0}
	};

	while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {

		switch (opt) {

		case 'C':
			audio_input = atoi(optarg);
			break;

		case 'P':
			audio_output = atoi(optarg);
			break;

		case 'a':
            multicast_ip = strdup(optarg);
            break;

		case 'p':
			udp_port = atoi(optarg);
			break;

		case 'h':
			usage();
			return -1;
		}
	}

    jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackFloatEncoder, 0, 2 };
    jack_master_t result;

    printf("Waiting for a master...\n");

    if ((net = jack_net_slave_open(multicast_ip, udp_port, "net_slave", &request, &result)) == 0) {
    	fprintf(stderr, "JACK server not running?\n");
		return 1;
	}

    printf("Master is found and running...\n");

    jack_set_net_slave_process_callback(net, net_process, NULL);
    jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL);

    if (jack_net_slave_activate(net) != 0) {
    	fprintf(stderr, "Cannot activate slave client\n");
		return 1;
	}

    /* install a signal handler to properly quits jack client */
#ifdef WIN32
	signal(SIGINT, signal_handler);
    signal(SIGABRT, signal_handler);
	signal(SIGTERM, signal_handler);
#else
	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);
#endif

    /* run until interrupted */
	while (1) {
	#ifdef WIN32
		Sleep(1000);
	#else
		sleep(1);
	#endif
	};

    // Wait for application end
    jack_net_slave_deactivate(net);
    jack_net_slave_close(net);
    exit(0);
}
07070100000021000081A400000000000000000000000161E2F7EE00001F0D000000000000000000000000000000000000003600000000jack-example-tools-1/example-clients/server_control.c/*
 	Copyright (C) 2008 Grame
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#if !defined(__JACK1__) && !defined(__JACK2__)
# error neither __JACK1__ or __JACK2__ is defined, this cannot happen
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <jack/jack.h>
#include <jack/control.h>

static jackctl_driver_t * jackctl_server_get_driver(jackctl_server_t *server, const char *driver_name)
{
    const JSList * node_ptr = jackctl_server_get_drivers_list(server);

    while (node_ptr) {
        if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0) {
            return (jackctl_driver_t *)node_ptr->data;
        }
        node_ptr = jack_slist_next(node_ptr);
    }

    return NULL;
}

static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server, const char *internal_name)
{
    const JSList * node_ptr = jackctl_server_get_internals_list(server);

    while (node_ptr) {
        if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0) {
            return (jackctl_internal_t *)node_ptr->data;
        }
        node_ptr = jack_slist_next(node_ptr);
    }

    return NULL;
}

#ifdef __JACK1__
static jackctl_parameter_t *
jackctl_get_parameter(
    const JSList * parameters_list,
    const char * parameter_name)
{
    while (parameters_list)
    {
        if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0)
        {
            return (jackctl_parameter_t *)parameters_list->data;
        }

        parameters_list = jack_slist_next(parameters_list);
    }

    return NULL;
}
#endif

static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type)
{
    switch (type) {
    
        case JackParamInt:
            printf("parameter value = %d\n", value.i);
            break;
            
         case JackParamUInt:
            printf("parameter value = %u\n", value.ui);
            break;
            
         case JackParamChar:
            printf("parameter value = %c\n", value.c);
            break;
        
         case JackParamString:
            printf("parameter value = %s\n", value.str);
            break;
            
         case JackParamBool:
            printf("parameter value = %d\n", value.b);
            break;
     }
}

static void print_parameters(const JSList * node_ptr)
{
    while (node_ptr != NULL) {
        jackctl_parameter_t * parameter = (jackctl_parameter_t *)node_ptr->data;
        printf("\nparameter name = %s\n", jackctl_parameter_get_name(parameter));
        printf("parameter id = %c\n", jackctl_parameter_get_id(parameter));
        printf("parameter short decs = %s\n", jackctl_parameter_get_short_description(parameter));
        printf("parameter long decs = %s\n", jackctl_parameter_get_long_description(parameter));
        print_value(jackctl_parameter_get_default_value(parameter), jackctl_parameter_get_type(parameter));
        node_ptr = jack_slist_next(node_ptr);
    }
}

static void print_driver(jackctl_driver_t * driver)
{
    printf("\n--------------------------\n");
    printf("driver = %s\n", jackctl_driver_get_name(driver));
    printf("-------------------------- \n");
    print_parameters(jackctl_driver_get_parameters(driver)); 
}

static void print_internal(jackctl_internal_t * internal)
{
    printf("\n-------------------------- \n");
    printf("internal = %s\n", jackctl_internal_get_name(internal));
    printf("-------------------------- \n");
    print_parameters(jackctl_internal_get_parameters(internal));
}

static void usage()
{
	fprintf (stderr, "\n"
					"usage: jack_server_control \n"
					"              [ --driver OR -d driver_name ]\n"
					"              [ --client OR -c client_name ]\n"
	);
}

int main(int argc, char *argv[])
{
    jackctl_server_t * server;
    const JSList * parameters;
    const JSList * drivers;
    const JSList * internals;
    const JSList * node_ptr;
#ifdef __JACK1__
    sigset_t signals;
#endif
#ifdef __JACK2__
    jackctl_sigmask_t * sigmask;
#endif
    int opt, option_index;
    const char* driver_name = "dummy";
    const char* client_name = "audioadapter";

    const char *options = "d:c:";
	struct option long_options[] = {
		{"driver", 1, 0, 'd'},
		{"client", 1, 0, 'c'},
	};
    
#ifdef __JACK1__
 	while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
#endif
#ifdef __JACK2__
 	while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) {
#endif
		switch (opt) {
			case 'd':
				driver_name = optarg;
				break;
			case 'c':
				client_name = optarg;
				break;
            default:
				usage();
                exit(0);
		}
	}
    
#ifdef __JACK1__
	server = jackctl_server_create(NULL, NULL);
#endif
#ifdef __JACK2__
	server = jackctl_server_create2(NULL, NULL, NULL);
#endif
    parameters = jackctl_server_get_parameters(server);
    
    /*
    jackctl_parameter_t* param;
    union jackctl_parameter_value value;
    param = jackctl_get_parameter(parameters, "verbose");
    if (param != NULL) {
        value.b = true;
        jackctl_parameter_set_value(param, &value);
    }
    */
    
    printf("\n========================== \n");
    printf("List of server parameters \n");
    printf("========================== \n");
    
    print_parameters(parameters);
    
    printf("\n========================== \n");
    printf("List of drivers \n");
    printf("========================== \n");
    
    drivers = jackctl_server_get_drivers_list(server);
    node_ptr = drivers;
    while (node_ptr != NULL) {
        print_driver((jackctl_driver_t *)node_ptr->data);
        node_ptr = jack_slist_next(node_ptr);
    }
    
    printf("\n========================== \n");
    printf("List of internal clients \n");
    printf("========================== \n");
    
    internals = jackctl_server_get_internals_list(server);
    node_ptr = internals;
    while (node_ptr != NULL) {
        print_internal((jackctl_internal_t *)node_ptr->data);
        node_ptr = jack_slist_next(node_ptr);
    }
#ifdef __JACK1__
    signals = jackctl_setup_signals(0);

    jackctl_server_start(server, jackctl_server_get_driver(server, driver_name));
#endif
#ifdef __JACK2__
    jackctl_server_open(server, jackctl_server_get_driver(server, driver_name));
    jackctl_server_start(server);
#endif

    jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name));
    
    /*
    // Switch master test
    
    jackctl_driver_t* master;
    
    usleep(5000000);
    printf("jackctl_server_load_master\n");
    master = jackctl_server_get_driver(server, "coreaudio");
    jackctl_server_switch_master(server, master);
    
    usleep(5000000);
    printf("jackctl_server_load_master\n");
    master = jackctl_server_get_driver(server, "dummy");
    jackctl_server_switch_master(server, master);
    
    */
      
#ifdef __JACK1__
    jackctl_wait_signals(signals);
#endif
#ifdef __JACK2__
    sigmask = jackctl_setup_signals(0);
    jackctl_wait_signals(sigmask);
    jackctl_server_stop(server);
    jackctl_server_close(server);
#endif
    jackctl_server_destroy(server);
    return 0;
}
07070100000022000081A400000000000000000000000161E2F7EE00000CB1000000000000000000000000000000000000003000000000jack-example-tools-1/example-clients/showtime.c/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <inttypes.h>

#include <jack/jack.h>
#include <jack/transport.h>

jack_client_t *client;

static void
showtime ()
{
	jack_position_t current;
	jack_transport_state_t transport_state;
	jack_nframes_t frame_time;

	transport_state = jack_transport_query (client, &current);
	frame_time = jack_frame_time (client);

	printf ("frame = %u  frame_time = %u usecs = %" PRIu64 "\t",  current.frame, frame_time, current.usecs);

	switch (transport_state) {
	case JackTransportStopped:
		printf ("state: Stopped");
		break;
	case JackTransportRolling:
		printf ("state: Rolling");
		break;
	case JackTransportStarting:
		printf ("state: Starting");
		break;
	default:
		printf ("state: [unknown]");
	}

	if (current.valid & JackPositionBBT)
		printf ("\tBBT: %3" PRIi32 "|%" PRIi32 "|%04"
			PRIi32, current.bar, current.beat, current.tick);

	if (current.valid & JackPositionTimecode)
		printf ("\tTC: (%.6f, %.6f)",
			current.frame_time, current.next_time);

	if (current.valid & JackBBTFrameOffset)
		printf ("\tBBT offset: (%" PRIi32 ")",
			current.bbt_offset);

	if (current.valid & JackAudioVideoRatio)
		printf ("\taudio/video: (%f)",
			current.audio_frames_per_video_frame);

	if (current.valid & JackVideoFrameOffset) {
		if (current.video_offset) {
			printf ("\t video@: (%" PRIi32 ")", current.video_offset);
		} else {
			printf ("\t no video");
		}
	}

	printf ("\n");
}

static void
jack_shutdown (void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit (1);
}

void
signal_handler (int sig)
{
	jack_client_close (client);
	fprintf (stderr, "signal received, exiting ...\n");
	exit (0);
}

int
main (int argc, char *argv[])
{
	/* try to become a client of the JACK server */

	if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}

#ifndef WIN32
	signal (SIGQUIT, signal_handler);
	signal (SIGHUP, signal_handler);
#endif

	signal (SIGTERM, signal_handler);
	signal (SIGINT, signal_handler);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* tell the JACK server that we are ready to roll */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	while (1) {
		usleep (20);
		showtime ();
	}

	jack_client_close (client);
	exit (0);
}
07070100000023000081A400000000000000000000000161E2F7EE00002DD0000000000000000000000000000000000000003300000000jack-example-tools-1/example-clients/simdtests.cpp/*
 *  simdtests.c -- test accuracy and performance of simd optimizations
 *
 *  Copyright (C) 2017 Andreas Mueller.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* We must include all headers memops.c includes to avoid trouble with
 * out namespace game below.
 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#ifdef __linux__
#include <endian.h>
#endif
#include "memops.h"

#if defined (__SSE2__) && !defined (__sun__)
#include <emmintrin.h>
#ifdef __SSE4_1__
#include <smmintrin.h>
#endif
#endif

#if defined (__ARM_NEON__) || defined (__ARM_NEON)
#include <arm_neon.h>
#endif

// our additional headers
#include <time.h>

/* Dirty: include mempos.c twice the second time with SIMD disabled
 * so we can compare aceelerated non accelerated
 */
namespace accelerated {
#include "../common/memops.c"
}

namespace origerated {
#ifdef __SSE2__
#undef __SSE2__
#endif

#ifdef __ARM_NEON__
#undef __ARM_NEON__
#endif

#ifdef __ARM_NEON
#undef __ARM_NEON
#endif

#include "../common/memops.c"
}

// define conversion function types
typedef void (*t_jack_to_integer)(
	char *dst,
	jack_default_audio_sample_t *src,
	unsigned long nsamples,
	unsigned long dst_skip,
	dither_state_t *state);

typedef void (*t_integer_to_jack)(
	jack_default_audio_sample_t *dst,
	char *src,
	unsigned long nsamples,
	unsigned long src_skip);

// define/setup test case data
typedef struct test_case_data {
	uint32_t frame_size;
	uint32_t sample_size;
	bool reverse;
	t_jack_to_integer jack_to_integer_accel;
	t_jack_to_integer jack_to_integer_orig;
	t_integer_to_jack integer_to_jack_accel;
	t_integer_to_jack integer_to_jack_orig;
	dither_state_t *ditherstate;
	const char *name;
} test_case_data_t;

test_case_data_t test_cases[] = {
	{
		4,
		3,
		true,
		accelerated::sample_move_d32u24_sSs,
		origerated::sample_move_d32u24_sSs,
		accelerated::sample_move_dS_s32u24s,
		origerated::sample_move_dS_s32u24s,
		NULL,
		"32u24s" },
	{
		4,
		3,
		false,
		accelerated::sample_move_d32u24_sS,
		origerated::sample_move_d32u24_sS,
		accelerated::sample_move_dS_s32u24,
		origerated::sample_move_dS_s32u24,
		NULL,
		"32u24" },
	{
		4,
		3,
		true,
		accelerated::sample_move_d32l24_sSs,
		origerated::sample_move_d32l24_sSs,
		accelerated::sample_move_dS_s32l24s,
		origerated::sample_move_dS_s32l24s,
		NULL,
		"32l24s" },
	{
		4,
		3,
		false,
		accelerated::sample_move_d32l24_sS,
		origerated::sample_move_d32l24_sS,
		accelerated::sample_move_dS_s32l24,
		origerated::sample_move_dS_s32l24,
		NULL,
		"32l24" },
	{
		3,
		3,
		true,
		accelerated::sample_move_d24_sSs,
		origerated::sample_move_d24_sSs,
		accelerated::sample_move_dS_s24s,
		origerated::sample_move_dS_s24s,
		NULL,
		"24s" },
	{
		3,
		3,
		false,
		accelerated::sample_move_d24_sS,
		origerated::sample_move_d24_sS,
		accelerated::sample_move_dS_s24,
		origerated::sample_move_dS_s24,
		NULL,
		"24" },
	{
		2,
		2,
		true,
		accelerated::sample_move_d16_sSs,
		origerated::sample_move_d16_sSs,
		accelerated::sample_move_dS_s16s,
		origerated::sample_move_dS_s16s,
		NULL,
		"16s" },
	{
		2,
		2,
		false,
		accelerated::sample_move_d16_sS,
		origerated::sample_move_d16_sS,
		accelerated::sample_move_dS_s16,
		origerated::sample_move_dS_s16,
		NULL,
		"16" },
};

// we need to repeat for better accuracy at time measurement
const uint32_t retry_per_case = 1000;

// setup test buffers
#define TESTBUFF_SIZE 1024
jack_default_audio_sample_t jackbuffer_source[TESTBUFF_SIZE];
// integer buffers: max 4 bytes per value / * 2 for stereo
char integerbuffer_accel[TESTBUFF_SIZE*4*2];
char integerbuffer_orig[TESTBUFF_SIZE*4*2];
// float buffers
jack_default_audio_sample_t jackfloatbuffer_accel[TESTBUFF_SIZE];
jack_default_audio_sample_t jackfloatbuffer_orig[TESTBUFF_SIZE];

// comparing unsigned makes life easier
uint32_t extract_integer(
	char* buff,
	uint32_t offset,
	uint32_t frame_size,
	uint32_t sample_size,
	bool big_endian)
{
	uint32_t retval = 0;
	unsigned char* curr;
	uint32_t mult = 1;
	if(big_endian) {
		curr = (unsigned char*)buff + offset + sample_size-1;
		for(uint32_t i=0; i<sample_size; i++) {
			retval += *(curr--) * mult;
			mult*=256;
		}
	}
	else {
		curr = (unsigned char*)buff + offset + frame_size-sample_size;
		for(uint32_t i=0; i<sample_size; i++) {
			retval += *(curr++) * mult;
			mult*=256;
		}
	}
	return retval;
}

int main(int argc, char *argv[])
{
//	parse_arguments(argc, argv);
	uint32_t maxerr_displayed = 10;

	// fill jackbuffer
	for(int i=0; i<TESTBUFF_SIZE; i++) {
		// ramp
		jack_default_audio_sample_t value =
			((jack_default_audio_sample_t)((i % TESTBUFF_SIZE) - TESTBUFF_SIZE/2)) / (TESTBUFF_SIZE/2);
		// force clipping
		value *= 1.02;
		jackbuffer_source[i] = value;
	}

	for(uint32_t testcase=0; testcase<sizeof(test_cases)/sizeof(test_case_data_t); testcase++) {
		// test mono/stereo
		for(uint32_t channels=1; channels<=2; channels++) {
			//////////////////////////////////////////////////////////////////////////////
			// jackfloat -> integer

			// clean target buffers
			memset(integerbuffer_accel, 0, sizeof(integerbuffer_accel));
			memset(integerbuffer_orig, 0, sizeof(integerbuffer_orig));
			// accel
			clock_t time_to_integer_accel = clock();
			for(uint32_t repetition=0; repetition<retry_per_case; repetition++)
			{
				test_cases[testcase].jack_to_integer_accel(
					integerbuffer_accel,
					jackbuffer_source,
					TESTBUFF_SIZE,
					test_cases[testcase].frame_size*channels,
					test_cases[testcase].ditherstate);
			}
			float timediff_to_integer_accel = ((float)(clock() - time_to_integer_accel)) / CLOCKS_PER_SEC;
			// orig
			clock_t time_to_integer_orig = clock();
			for(uint32_t repetition=0; repetition<retry_per_case; repetition++)
			{
				test_cases[testcase].jack_to_integer_orig(
					integerbuffer_orig,
					jackbuffer_source,
					TESTBUFF_SIZE,
					test_cases[testcase].frame_size*channels,
					test_cases[testcase].ditherstate);
			}
			float timediff_to_integer_orig = ((float)(clock() - time_to_integer_orig)) / CLOCKS_PER_SEC;
			// output performance results
			printf(
				"JackFloat->Integer @%7.7s/%u: Orig %7.6f sec / Accel %7.6f sec -> Win: %5.2f %%\n",
				test_cases[testcase].name,
				channels,
				timediff_to_integer_orig,
				timediff_to_integer_accel,
				(timediff_to_integer_orig/timediff_to_integer_accel-1)*100.0);
			uint32_t int_deviation_max = 0;
			uint32_t int_error_count = 0;
			// output error (avoid spam -> limit error lines per test case)
			for(uint32_t sample=0; sample<TESTBUFF_SIZE; sample++) {
				uint32_t sample_offset = sample*test_cases[testcase].frame_size*channels;
				// compare both results
				uint32_t intval_accel=extract_integer(
					integerbuffer_accel,
					sample_offset,
					test_cases[testcase].frame_size,
					test_cases[testcase].sample_size,
#if __BYTE_ORDER == __BIG_ENDIAN
					!test_cases[testcase].reverse);
#else
					test_cases[testcase].reverse);
#endif
				uint32_t intval_orig=extract_integer(
					integerbuffer_orig,
					sample_offset,
					test_cases[testcase].frame_size,
					test_cases[testcase].sample_size,
#if __BYTE_ORDER == __BIG_ENDIAN
					!test_cases[testcase].reverse);
#else
					test_cases[testcase].reverse);
#endif
				// allow a deviation of 1
				if(intval_accel>intval_orig+1 || intval_orig>intval_accel+1) {
					if(int_error_count<maxerr_displayed) {
						printf("Value error sample %u:", sample);
						printf(" Orig 0x");
						char formatstr[10];
						sprintf(formatstr, "%%0%uX", test_cases[testcase].sample_size*2);
						printf(formatstr, intval_orig);
						printf(" Accel 0x");
						printf(formatstr, intval_accel);
						printf("\n");
					}
					int_error_count++;
					uint32_t int_deviation;
					if(intval_accel > intval_orig)
						int_deviation = intval_accel-intval_orig;
					else
						int_deviation = intval_orig-intval_accel;
					if(int_deviation > int_deviation_max)
						int_deviation_max = int_deviation;
				}
			}
			printf(
				"JackFloat->Integer @%7.7s/%u: Errors: %u Max deviation %u\n",
				test_cases[testcase].name,
				channels,
				int_error_count,
				int_deviation_max);

			//////////////////////////////////////////////////////////////////////////////
			// integer -> jackfloat

			// clean target buffers
			memset(jackfloatbuffer_accel, 0, sizeof(jackfloatbuffer_accel));
			memset(jackfloatbuffer_orig, 0, sizeof(jackfloatbuffer_orig));
			// accel
			clock_t time_to_float_accel = clock();
			for(uint32_t repetition=0; repetition<retry_per_case; repetition++)
			{
				test_cases[testcase].integer_to_jack_accel(
					jackfloatbuffer_accel,
					integerbuffer_orig,
					TESTBUFF_SIZE,
					test_cases[testcase].frame_size*channels);
			}
			float timediff_to_float_accel = ((float)(clock() - time_to_float_accel)) / CLOCKS_PER_SEC;
			// orig
			clock_t time_to_float_orig = clock();
			for(uint32_t repetition=0; repetition<retry_per_case; repetition++)
			{
				test_cases[testcase].integer_to_jack_orig(
					jackfloatbuffer_orig,
					integerbuffer_orig,
					TESTBUFF_SIZE,
					test_cases[testcase].frame_size*channels);
			}
			float timediff_to_float_orig = ((float)(clock() - time_to_float_orig)) / CLOCKS_PER_SEC;
			// output performance results
			printf(
				"Integer->JackFloat @%7.7s/%u: Orig %7.6f sec / Accel %7.6f sec -> Win: %5.2f %%\n",
				test_cases[testcase].name,
				channels,
				timediff_to_float_orig,
				timediff_to_float_accel,
				(timediff_to_float_orig/timediff_to_float_accel-1)*100.0);
			jack_default_audio_sample_t float_deviation_max = 0.0;
			uint32_t float_error_count = 0;
			// output error (avoid spam -> limit error lines per test case)
			for(uint32_t sample=0; sample<TESTBUFF_SIZE; sample++) {
				// For easier estimation/readability we scale floats back to integer
				jack_default_audio_sample_t sample_scaling;
				switch(test_cases[testcase].sample_size) {
					case 2:
						sample_scaling = SAMPLE_16BIT_SCALING;
						break;
					default:
						sample_scaling = SAMPLE_24BIT_SCALING;
						break;
				}
				jack_default_audio_sample_t floatval_accel = jackfloatbuffer_accel[sample] * sample_scaling;
				jack_default_audio_sample_t floatval_orig = jackfloatbuffer_orig[sample] * sample_scaling;
				// compare both results
				jack_default_audio_sample_t float_deviation;
				if(floatval_accel > floatval_orig)
					float_deviation = floatval_accel-floatval_orig;
				else
					float_deviation = floatval_orig-floatval_accel;
				if(float_deviation > float_deviation_max)
					float_deviation_max = float_deviation;
				// deviation > half bit => error
				if(float_deviation > 0.5) {
					if(float_error_count<maxerr_displayed) {
						printf("Value error sample %u:", sample);
						printf(" Orig %8.1f Accel %8.1f\n", floatval_orig, floatval_accel);
					}
					float_error_count++;
				}
			}
			printf(
				"Integer->JackFloat @%7.7s/%u: Errors: %u Max deviation %f\n",
				test_cases[testcase].name,
				channels,
				float_error_count,
				float_deviation_max);

			printf("\n");
		}
	}
	return 0;
}
07070100000024000081A400000000000000000000000161E2F7EE0000151A000000000000000000000000000000000000003500000000jack-example-tools-1/example-clients/simple_client.c/** @file simple_client.c
 *
 * @brief This simple client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <jack/jack.h>

jack_port_t *output_port1, *output_port2;
jack_client_t *client;

#ifndef M_PI
#define M_PI  (3.14159265)
#endif

#define TABLE_SIZE   (200)
typedef struct
{
	float sine[TABLE_SIZE];
	int left_phase;
	int right_phase;
}
paTestData;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client follows a simple rule: when the JACK transport is
 * running, copy the input port to the output.  When it stops, exit.
 */

int
process (jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *out1, *out2;
	paTestData *data = (paTestData*)arg;
	int i;

	out1 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port1, nframes);
	out2 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port2, nframes);

	for( i=0; i<nframes; i++ )
	{
		out1[i] = data->sine[data->left_phase];  /* left */
		out2[i] = data->sine[data->right_phase];  /* right */
		data->left_phase += 1;
		if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
		data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
		if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
	}
    
	return 0;      
}

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown (void *arg)
{
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;
	paTestData data;
	int i;

	if (argc >= 2) {		/* client name specified? */
		client_name = argv[1];
		if (argc >= 3) {	/* server name specified? */
			server_name = argv[2];
			int my_option = JackNullOption | JackServerName;
			options = (jack_options_t)my_option;
		}
	} else {			/* use basename of argv[0] */
		client_name = strrchr(argv[0], '/');
		if (client_name == 0) {
			client_name = argv[0];
		} else {
			client_name++;
		}
	}

	for( i=0; i<TABLE_SIZE; i++ )
	{
		data.sine[i] = 0.2 * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
	}
	data.left_phase = data.right_phase = 0;
  

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, &data);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* create two ports */

	output_port1 = jack_port_register (client, "output1",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	output_port2 = jack_port_register (client, "output2",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((output_port1 == NULL) || (output_port2 == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */
 	
	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

	if (jack_connect (client, jack_port_name (output_port1), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	if (jack_connect (client, jack_port_name (output_port2), ports[1])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	jack_free (ports);
    
    /* install a signal handler to properly quits jack client */
#ifdef WIN32
	signal(SIGINT, signal_handler);
	signal(SIGABRT, signal_handler);
	signal(SIGTERM, signal_handler);
#else
	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);
#endif

	/* keep running until the Ctrl+C */

	while (1) {
	#ifdef WIN32 
		Sleep(1000);
	#else
		sleep (1);
	#endif
	}

	jack_client_close (client);
	exit (0);
}
07070100000025000081A400000000000000000000000161E2F7EE000013D7000000000000000000000000000000000000003D00000000jack-example-tools-1/example-clients/simple_session_client.c/** @file simple_session_client.c
 *
 * @brief This simple client demonstrates the most basic features of JACK
 * as they would be used by many applications.
 * this version also adds session manager functionality.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include <jack/jack.h>
#include <jack/types.h>
#include <jack/session.h>

jack_port_t *input_port;
jack_port_t *output_port;
jack_client_t *client;

int simple_quit = 0;

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client does nothing more than copy data from its input
 * port to its output port. It will exit when stopped by
 * the user (e.g. using Ctrl-C on a unix-ish operating system)
 */
int
process (jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *in, *out;

	in = jack_port_get_buffer (input_port, nframes);
	out = jack_port_get_buffer (output_port, nframes);
	memcpy (out, in,
		sizeof (jack_default_audio_sample_t) * nframes);

	return 0;
}

void
session_callback (jack_session_event_t *event, void *arg)
{
	char retval[100];
	printf ("session notification\n");
	printf ("path %s, uuid %s, type: %s\n", event->session_dir, event->client_uuid, event->type == JackSessionSave ? "save" : "quit");


	snprintf (retval, 100, "jack_simple_session_client %s", event->client_uuid);
	event->command_line = strdup (retval);

	jack_session_reply( client, event );

	if (event->type == JackSessionSaveAndQuit) {
		simple_quit = 1;
	}

	jack_session_event_free (event);
}

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown (void *arg)
{
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name = "simple";
	jack_status_t status;

	/* open a client connection to the JACK server */

	if( argc == 1 )
		client = jack_client_open (client_name, JackNullOption, &status );
	else if( argc == 2 )
		client = jack_client_open (client_name, JackSessionID, &status, argv[1] );

	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* tell the JACK server to call `session_callback()' if
	   the session is saved.
	*/

	jack_set_session_callback (client, session_callback, NULL);

	/* display the current sample rate.
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_port = jack_port_register (client, "output",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */


	/* only do the autoconnect when not reloading from a session.
	 * in case of a session reload, the SM will restore our connections
	 */

	if (argc==1) {

		ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
		if (ports == NULL) {
			fprintf(stderr, "no physical capture ports\n");
			exit (1);
		}

		if (jack_connect (client, ports[0], jack_port_name (input_port))) {
			fprintf (stderr, "cannot connect input ports\n");
		}

		free (ports);

		ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
		if (ports == NULL) {
			fprintf(stderr, "no physical playback ports\n");
			exit (1);
		}

		if (jack_connect (client, jack_port_name (output_port), ports[0])) {
			fprintf (stderr, "cannot connect output ports\n");
		}

		free (ports);
	}

	/* keep running until until we get a quit event */

	while (!simple_quit)
#ifdef WIN32
		Sleep(1*1000);
#else
		sleep(1);
#endif

	jack_client_close (client);
	exit (0);
}
07070100000026000081A400000000000000000000000161E2F7EE00001738000000000000000000000000000000000000003300000000jack-example-tools-1/example-clients/thru_client.c/** @file thru_client.c
 *
 * @brief This simple through client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <jack/jack.h>

jack_port_t **input_ports;
jack_port_t **output_ports;
jack_client_t *client;

static void signal_handler ( int sig )
{
    jack_client_close ( client );
    fprintf ( stderr, "signal received, exiting ...\n" );
    exit ( 0 );
}

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client follows a simple rule: when the JACK transport is
 * running, copy the input port to the output.  When it stops, exit.
 */

int
process ( jack_nframes_t nframes, void *arg )
{
    int i;
    jack_default_audio_sample_t *in, *out;
    for ( i = 0; i < 2; i++ )
    {
        in = jack_port_get_buffer ( input_ports[i], nframes );
        out = jack_port_get_buffer ( output_ports[i], nframes );
        memcpy ( out, in, nframes * sizeof ( jack_default_audio_sample_t ) );
    }
    return 0;
}

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown ( void *arg )
{
    free ( input_ports );
    free ( output_ports );
    exit ( 1 );
}

int
main ( int argc, char *argv[] )
{
    int i;
    const char **ports;
    const char *client_name;
    const char *server_name = NULL;
    jack_options_t options = JackNullOption;
    jack_status_t status;

    if ( argc >= 2 )        /* client name specified? */
    {
        client_name = argv[1];
        if ( argc >= 3 )    /* server name specified? */
        {
            server_name = argv[2];
            options |= JackServerName;
        }
    }
    else              /* use basename of argv[0] */
    {
        client_name = strrchr ( argv[0], '/' );
        if ( client_name == 0 )
        {
            client_name = argv[0];
        }
        else
        {
            client_name++;
        }
    }

    /* open a client connection to the JACK server */

    client = jack_client_open ( client_name, options, &status, server_name );
    if ( client == NULL )
    {
        fprintf ( stderr, "jack_client_open() failed, "
                  "status = 0x%2.0x\n", status );
        if ( status & JackServerFailed )
        {
            fprintf ( stderr, "Unable to connect to JACK server\n" );
        }
        exit ( 1 );
    }
    if ( status & JackServerStarted )
    {
        fprintf ( stderr, "JACK server started\n" );
    }
    if ( status & JackNameNotUnique )
    {
        client_name = jack_get_client_name ( client );
        fprintf ( stderr, "unique name `%s' assigned\n", client_name );
    }

    /* tell the JACK server to call `process()' whenever
       there is work to be done.
    */

    jack_set_process_callback ( client, process, 0 );

    /* tell the JACK server to call `jack_shutdown()' if
       it ever shuts down, either entirely, or if it
       just decides to stop calling us.
    */

    jack_on_shutdown ( client, jack_shutdown, 0 );

    /* create two ports pairs*/
    input_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) );
    output_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) );

    char port_name[16];
    for ( i = 0; i < 2; i++ )
    {
        sprintf ( port_name, "input_%d", i + 1 );
        input_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
        sprintf ( port_name, "output_%d", i + 1 );
        output_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
        if ( ( input_ports[i] == NULL ) || ( output_ports[i] == NULL ) )
        {
            fprintf ( stderr, "no more JACK ports available\n" );
            exit ( 1 );
        }
    }

    /* Tell the JACK server that we are ready to roll.  Our
     * process() callback will start running now. */

    if ( jack_activate ( client ) )
    {
        fprintf ( stderr, "cannot activate client" );
        exit ( 1 );
    }

    /* Connect the ports.  You can't do this before the client is
     * activated, because we can't make connections to clients
     * that aren't running.  Note the confusing (but necessary)
     * orientation of the driver backend ports: playback ports are
     * "input" to the backend, and capture ports are "output" from
     * it.
     */

    ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput );
    if ( ports == NULL )
    {
        fprintf ( stderr, "no physical capture ports\n" );
        exit ( 1 );
    }

    for ( i = 0; i < 2; i++ )
        if ( jack_connect ( client, ports[i], jack_port_name ( input_ports[i] ) ) )
            fprintf ( stderr, "cannot connect input ports\n" );

    free ( ports );

    ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsInput );
    if ( ports == NULL )
    {
        fprintf ( stderr, "no physical playback ports\n" );
        exit ( 1 );
    }

    for ( i = 0; i < 2; i++ )
        if ( jack_connect ( client, jack_port_name ( output_ports[i] ), ports[i] ) )
            fprintf ( stderr, "cannot connect input ports\n" );

    free ( ports );

    /* install a signal handler to properly quits jack client */
#ifdef WIN32
    signal ( SIGINT, signal_handler );
    signal ( SIGABRT, signal_handler );
    signal ( SIGTERM, signal_handler );
#else
    signal ( SIGQUIT, signal_handler );
    signal ( SIGTERM, signal_handler );
    signal ( SIGHUP, signal_handler );
    signal ( SIGINT, signal_handler );
#endif

    /* keep running until the transport stops */

    while (1)
    {
#ifdef WIN32
        Sleep ( 1000 );
#else
        sleep ( 1 );
#endif
    }

    jack_client_close ( client );
    exit ( 0 );
}
07070100000027000081A400000000000000000000000161E2F7EE000012E6000000000000000000000000000000000000003800000000jack-example-tools-1/example-clients/transport_client.c/** @file transport_client.c
 *
 * @brief This client demonstrates very simple use of the JACK
 * transport API. Compare it with the simple_client example,
 * which is even simpler. It also demonstrates taking a client
 * name and optionally server name from the command line, rather 
 * than hard-coding either of these names.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;
jack_client_t *client;

/* a simple state machine for this client */
volatile enum {
	Init,
	Run,
	Exit
} client_state = Init;

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client follows a simple rule: when the JACK transport is
 * running, copy the input port to the output.  When it stops, exit.
 */
int
process (jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *in, *out;
	jack_transport_state_t ts = jack_transport_query(client, NULL);

	if (ts == JackTransportRolling) {

		if (client_state == Init)
			client_state = Run;

		in = jack_port_get_buffer (input_port, nframes);
		out = jack_port_get_buffer (output_port, nframes);
		memcpy (out, in,
			sizeof (jack_default_audio_sample_t) * nframes);

	} else if (ts == JackTransportStopped) {

		if (client_state == Run)
			client_state = Exit;
	}

	return 0;      
}

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
void
jack_shutdown (void *arg)
{
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;

	if (argc >= 2) {		/* client name specified? */
		client_name = argv[1];
		if (argc >= 3) {	/* server name specified? */
			server_name = argv[2];
			options |= JackServerName;
		}
	} else {			/* use basename of argv[0] */
		client_name = strrchr(argv[0], '/');
		if (client_name == 0) {
			client_name = argv[0];
		} else {
			client_name++;
		}
	}

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate. 
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_port = jack_port_register (client, "output",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}

	if (jack_connect (client, ports[0], jack_port_name (input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
	}

	free (ports);
	
	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	free (ports);

	/* keep running until the transport stops */

	while (client_state != Exit) {
		sleep (1);
	}

	jack_client_close (client);
	exit (0);
}
07070100000028000081A400000000000000000000000161E2F7EE000008D6000000000000000000000000000000000000002E00000000jack-example-tools-1/example-clients/zombie.c/*
    Copyright (C) 2002 Jeremy Hall

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: zombie.c,v 1.1 2005/08/18 11:42:08 letz Exp $
*/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <jack/jack.h>

int running = 1;
int count = 0;
jack_port_t* output_port;

static int
process(jack_nframes_t nframes, void* arg)
{
	if (count++ == 1000) {
        printf("process block\n");
        //while (1) {}
#if WIN32
	Sleep(1*1000);
#else
	sleep(1);
#endif
    }

    return 0;
}

static void
shutdown_handler (void *arg)
{
    printf("shutdown \n");
    running = 0;
}

int
main (int argc, char *argv[])
{
	jack_client_t* client = NULL;
    /* try to become a client of the JACK server */
	if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		goto error;
	}

    jack_set_process_callback (client, process, NULL);
    jack_on_shutdown(client, shutdown_handler, NULL);
    output_port = jack_port_register (client, "port1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

	/* tell the JACK server that we are ready to roll */
	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		goto error;
	}

    jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2");

    while (running) {
#if WIN32
        Sleep(1*1000);
#else
        sleep(1);
#endif
        printf ("run\n");
    }

    jack_deactivate (client);
	jack_client_close (client);
	return 0;

error:
    if (client)
        jack_client_close (client);
    return 1;
}

07070100000029000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000001900000000jack-example-tools-1/man0707010000002A000081A400000000000000000000000161E2F7EE00000E57000000000000000000000000000000000000002300000000jack-example-tools-1/man/alsa_in.0.TH ALSA_IO "1" "@DATE@" "@VERSION@"
.SH NAME
\fBalsa_in\fR, \fBalsa_out\fR \- Jack clients that perform I/O with an alternate audio interface
.SH SYNOPSIS
\fBalsa_in\fR [\fIoptions\fR]
.br
\fBalsa_out\fR [\fIoptions\fR]

.SH DESCRIPTION
A JACK client that opens a specified audio interface (different to the
one used by the JACK server, if any) and moves audio data between its
JACK ports and the interface. alsa_in will provide data from the
interface (potentially for capture); alsa_out will deliver data to it
(for playback).

The audio interface used by alsa_in/alsa_out does not need to be
synchronized with JACK backend (or the hardware it might be using).
alsa_in/alsa_out tries to resample the output stream in an attempt to
compensate for drift between the two clocks.

As of jack-0.116.3 this works almost perfectly. It takes some time, to reach
absolute resample-rate stability. So give it some minutes (its intended to be
running permanently anyways)

.SH OPTIONS
.TP
\fB\-j \fI jack_client_name\fR
.br
Set Client Name.
.TP
\fB\-d \fI alsa_device\fR  
.br
Use this Soundcard.
.TP
\fB\-v\fR  
.br
Verbose, prints out resample coefficient and other parameters useful for debugging, every 500ms.
also reports soft xruns. 
.TP
\fB\-i\fR  
.br
Instrumentation. This logs the 4 important parameters of the samplerate control algorithm every 1ms.
You can pipe this into a file, and plot it. Should only be necessary, if it does not work as
expected, and we need to adjust some of the obscure parameters, to make it work. 
Find me on irc.freenode.org #jack in order to set this up correctly.
.TP
\fB\-c \fI channels\fR  
.br
Set Number of channels.
.TP
\fB\-r \fI sample_rate\fR  
.br
Set sample_rate. The program resamples as necessary.
So you can connect a 44100 jackd to a soundcard only supporting
48000. (default is jack sample_rate)
.TP
\fB\-p \fI period_size\fR  
.br
Set the period size. It is not related to the jackd period_size.
Sometimes it affects the quality of the delay measurements.
Setting this lower than the jackd period_size will only work, if you
use a higher number of periods. 
.TP
\fB\-n \fI num_period\fR  
.br
Set number of periods. See note for period_size.
.TP
\fB\-q \fI quality\fR  
.br
Set the quality of the resampler from 0 to 4. can significanly reduce cpu usage.
.TP
\fB\-m \fI max_diff\fR  
.br
The value when a soft xrun occurs. Basically the window, in which
the dma pointer may jitter. I don't think its necessary to play with this anymore. 
.TP
\fB\-t \fI target_delay\fR  
.br
The delay alsa_io should try to approach. Same as for max_diff. It will be setup based on \-p and \-n
which is generally sufficient.
.TP
\fB\-s \fI smooth_array_size\fR  
.br
This parameter controls the size of the array used for smoothing the delay measurement. Its default is 256.
If you use a pretty low period size, you can lower the CPU usage a bit by decreasing this parameter.
However most CPU time is spent in the resampling so this will not be much.
.TP
\fB\-C \fI P Control Clamp\fR  
.br
If you have a PCI card, then the default value (15) of this parameter is too high for \-p64 \-n2... Setting it to 5 should fix that.
Be aware that setting this parameter too low, lets the hf noise on the delay measurement come through onto the resamplerate, so this
might degrade the quality of the output. (but its a threshold value, and it has been chosen, to mask the noise of a USB card,
which has an amplitude which is 50 times higher than that of a PCI card, so 5 won't lose you any quality on a PCI card)
.TP
\fB\-S \fI server_name\fR 
.br
Server to connect to. This option permits to attach to a named jack2 server.

.SH AUTHOR
Torben Hohn
0707010000002B000081A400000000000000000000000161E2F7EE00000013000000000000000000000000000000000000002400000000jack-example-tools-1/man/alsa_out.0.so man1/alsa_in.1
0707010000002C000081A400000000000000000000000161E2F7EE000001B3000000000000000000000000000000000000002800000000jack-example-tools-1/man/jack_bufsize.0.TH JACK_BUFSIZE "1" "@DATE@" "@VERSION@"
.SH NAME
jack_bufsize \- JACK toolkit client to change the JACK buffer size
.SH SYNOPSIS
.B jack_bufsize bufsize
.SH DESCRIPTION
.B jack_bufsize
jack_bufsize sets the size of the buffer (frames per period) used in JACK. 
This change happens on-line (the JACK server and its clients do not need to be 
restarted).
.br
When invoked without arguments, it prints the current bufsize, and exits.


0707010000002D000081A400000000000000000000000161E2F7EE0000022A000000000000000000000000000000000000002800000000jack-example-tools-1/man/jack_connect.0.TH JACK_CONNECT "1" "@DATE@" "@VERSION@"
.SH NAME
\fBjack_connect\fR, \fBjack_disconnect\fR \- JACK toolkit clients for connecting & disconnecting ports
.SH SYNOPSIS
\fB jack_connect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2
\fB jack_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2
.SH DESCRIPTION
\fBjack_connect\fR connects the two named ports. \fBjack_disconnect\fR disconnects the two named ports.
.SH RETURNS
The exit status is zero if successful, 1 otherwise

0707010000002E000081A400000000000000000000000161E2F7EE00000018000000000000000000000000000000000000002B00000000jack-example-tools-1/man/jack_disconnect.0.so man1/jack_connect.1
0707010000002F000081A400000000000000000000000161E2F7EE00000280000000000000000000000000000000000000002A00000000jack-example-tools-1/man/jack_freewheel.0.TH JACK_FREEWHEEL "1" "@DATE@" "@VERSION@"
.SH NAME
jack_freewheel \- JACK toolkit client to control freewheeling mode
.SH SYNOPSIS
.B jack_freewheel [y|n]
.SH DESCRIPTION
.B jack_freewheel
Turns freewheeling mode on (y) or off (n). While in freewheeling mode,
the JACK server does not wait in between process() calls, and does not
read or write data from/to any audio interface. That results in the JACK graph
processing data as fast as possible. Freewheeling makes fast exports to 
files possible.
.PP
There is no useful reason to use this tool other than testing. JACK
clients that use freewheeling will turn it on and off themselves.

07070100000030000081A400000000000000000000000161E2F7EE00000157000000000000000000000000000000000000003000000000jack-example-tools-1/man/jack_impulse_grabber.0.TH JACK_IMPULSE_GRABBER "1" "@DATE@" "@VERSION@"
.SH NAME
jack_impulse_grabber \- JACK toolkit client to grab an impulse (response)
.SH SYNOPSIS
\fBjack_impulse_grabber\fR \fB-d\fR \fIduration\fR [\fI-f\fR (C|gnuplot)]
.SH DESCRIPTION
\fBjack_impulse_grabber\fR is a JACK example client for collecting
impulses recordings from JACK ports.



07070100000031000081A400000000000000000000000161E2F7EE00000B83000000000000000000000000000000000000002800000000jack-example-tools-1/man/jack_iodelay.0.TH JACK_IODELAY "1" "@DATE@" "@VERSION@"
.SH NAME
jack_iodelay \- JACK toolkit client to measure roundtrip latency
.SH SYNOPSIS
.B jack_iodelay
.SH DESCRIPTION
.B jack_iodelay
will create one input and one output port, and then
measures the latency (signal delay) between them. For this to work,
the output port must be connected to its input port. The measurement
is accurate to a resolution of greater than 1 sample.
.PP
The expected use is to connect jack_iodelay's output port to a
hardware playback port, then use a physical loopback cable from the
corresponding hardware output connector to an input connector, and to
connect that corresponding hardware capture port to jack_iodelay's
input port. This creates a roundtrip that goes through any
analog-to-digital and digital-to-analog converters that are present in
the audio hardware.
.PP
Although the hardware loopback latency is the expected use, it is also
possible to use jack_iodelay to measure the latency along any fully
connected signal path, such as those involving other JACK clients.
.PP
Once jack_iodelay completes its measurement it will print the total
latency it has detected. This will include the JACK buffer length in
addition to any other latency in the signal path. It will continue to
print the value every 0.5 seconds so that if you wish you can
vary aspects of the signal path to see their effect on the measured
latency.
.PP
If no incoming signal is detected from the input port, jack_iodelay
will print 
.PP
\fT Signal below threshold... .\fR
.PP
every second until this changes (e.g. until you establish the correct
connections).
.PP
To use the value measured by jack_iodelay with the -I and -O arguments
of a JACK backend (also called Input Latency and Output Latency in the
setup dialog of qjackctl), you must subtract the JACK buffer size from
the result. The buffer size is determined by multiplying the number of
frames per period (given to the jackd backend by the -p or --period
option) by the number of periods per buffer (given to the jackd
backend by the -n or --nperiods option).  Note that JACK2 will add an
implicit additional period when using the default asynchronous mode,
so for JACK1 or JACK2 in synchronous mode, the buffer size is n*p, but
for JACK2 in asynchronous mode the buffer size is (n+1)*p.  Once the
JACK buffer size is subtracted from the measured latency, the result
is the "extra" latency due to the interface hardware. Then, if you
believe that the latency is equally distributed between the input and
output parts of your audio hardware (extremely likely), divide the
result by two and use that for input and output latency
values. Doing this measurement will enable JACK clients that use the
JACK latency API to accurately position/delay audio to keep signals
synchronized even when there are inherent delays in the end-to-end
signal pathways.
.SH AUTHOR
Originally written in C++ by Fons Adriaensen, ported to C by Torben Hohn.
07070100000032000081A400000000000000000000000161E2F7EE00000392000000000000000000000000000000000000002500000000jack-example-tools-1/man/jack_load.0.TH JACK_LOAD "1" "@DATE@" "@VERSION@"
.SH NAME
jack_load \- JACK toolkit client for loading in-process clients
.SH SYNOPSIS
\fBjack_load\fR [ \fI-i\fR initstring ] [ \fI-s\fR servername ] [\fI-w\fR ] client-name so-name [ initstring ]
.SH DESCRIPTION
\fBjack_load\fR is a JACK toolkit client. It loads the specified plugin and creates an in-process client.
.SH ARGUMENTS
.PP
The client-name must be a currently unused client name.
.PP
The so-name is the name of file that client code is stored in (typically, \fIclientname.so\fR)
.SH OPTIONS
.TP
\fB-i\fR, \fB--init\fR init-string
.br
initialization string passed to the in-process client. Note that this can also be specified as the last argument on the command line.
.TP
\fB-s\fR, \fB--server\fR servername
.br
Name of JACK server to connect to
.TP
\fB-w\fR, \fB--wait\fR
Wait for a signal (eg. from Ctrl-c) and then unload the client.
.SH AUTHOR
Jeremy Hall


07070100000033000081A400000000000000000000000161E2F7EE0000042C000000000000000000000000000000000000002400000000jack-example-tools-1/man/jack_lsp.0.TH JACK_LSP "1" "@DATE@" "@VERSION@"
.SH NAME
jack_lsp \- JACK toolkit client to list information on ports
.SH SYNOPSIS
\fBjack_lsp\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-AclLptvh\fR ]
.SH DESCRIPTION
\fBjack_lsp\fR lists all known ports associated with a JACK
server. It can also optionally list various kinds of information about each port.
.SH OPTIONS
.TP
\fB-s\fR, \fB--server\fR \fIservername\fR
.br
Connect to the jack server named \fIservername\fR
.TP
\fB-A\fR, \fB--aliases\fR
.br
List aliases for each port
.TP
\fB-c\fR, \fB--connections\fR
.br
List connections to/from each port
.TP
\fB-l\fR, \fB--latency\fR
.br
Display per-port latency in frames at each port
.TP
\fB-L\fR, \fI--latency\fR
.br
Display total latency in frames at each port
.TP
\fB-p\fR, \fB--properties\fR
.br
Display port properties. Output may include input|output, can-monitor, physical, terminal
.TP
\fB-t\fR, \fB--type\fR
.br
Display port type
.TP
\fB-h\fR, \fB--help\fR
.br
Display help/usage message
.TP
\fB-v\fR, \fB--version\fR
.br
Output version information and exit


07070100000034000081A400000000000000000000000161E2F7EE00000445000000000000000000000000000000000000002600000000jack-example-tools-1/man/jack_metro.0.TH JACK_METRO "1" "@DATE@" "@VERSION@"
.SH NAME
jack_metro \- JACK toolkit metronome
.SH SYNOPSIS
\fBjack_metro\fR [ \fI-n\fR name ] [ \fI-f\fR hz ] [ \fI-D\fR msecs ] [\fI-a\fR % ] [ \fI-d\fR % ] \fI-b\fR bpm 
.SH DESCRIPTION
\fBjack_metro\fR is a simple metronome for JACK. It generates a
synthetic "tick" sound for every beat. Note that is does \fBnot\fR
connect its output port by default - to hear the sound it makes you must
connect them using some other tool.
.SH OPTIONS
.TP
\fB-n\fR, \fB--name\fR
.br
Specify a name for this instance of the metronome.
.TP
\fB-f\fR, \fB--frequency\fR Hz
.br
Define the frequency of the "tick" in Hz.
.TP
\fB-D\fR, \fB--duration\fR msecs
.br
Define the duration of the "tick" in milliseconds.
.TP
\fB-a\fR, \fB--attack\fR %-age
.br
Define the duration of the attack phase of the "tick" as a percentage
of the duration.
.TP
\fB-d\fR, \fB--decay\fR %-age
.br
Define the duration of the decay phase of the "tick" as a percentage
of the duration.
.TP
\fB--b\fR, \fB--bpm\fR bpm
.br
Define the number of beats per minute.
.SH AUTHOR
Anthony Van Groningen

07070100000035000081A400000000000000000000000161E2F7EE000001FF000000000000000000000000000000000000002F00000000jack-example-tools-1/man/jack_monitor_client.0.TH JACK_CONNECT "1" "@DATE@" "@VERSION@"
.SH NAME
jack_monitor_client \- The JACK Audio Connection Kit example client
.SH SYNOPSIS
.B jack_monitor_client
client-name
.PP
The client-name must be the name of a existing client that monitoring is 
to be enabled for.
.SH DESCRIPTION
.B jack_monitor_client
is an example client for the JACK Audio Connection Kit. It enables
monitoring for the specified client.
.SH AUTHOR
Jeremy Hall
.PP
This manpage was written by Robert Jordens <jordens@debian.org> for Debian.

07070100000036000081A400000000000000000000000161E2F7EE0000093C000000000000000000000000000000000000002A00000000jack-example-tools-1/man/jack_netsource.0.TH JACK_NETSOURCE "1" "@DATE@" "@VERSION@"
.SH NAME
jack_netsource \- Netjack Master client for one slave
.SH SYNOPSIS
\fBjack_netsource\fR [ \fI-H\fR hostname ] [ \fIoptions\fR ]

.SH DESCRIPTION
\fBjack_netsource\fR The Master side of a netjack connection. Represents the slave jackd -dnet in the master jack graph.
Most connection parameters are configured via the netsource, and the slave will set itself up according to the commandline
option given to jack_netsource.
.br
Netjack allows low latency audio connections over general IP networks. When using opus for compression, it is even possible
to establish transatlantic links, with latencies not much over the actual ping time. 
.br
But the main usecase is of course a LAN, where it can achieve one jack period of latency.

.SH OPTIONS
.TP
\fB-h\fR this help text
.TP
\fB-H\fR \fIslave host\fR
.br
Host name of the slave JACK
.TP
\fB-o\fR \fInum channels\fR
.br
Number of audio playback channels
.TP
\fB-i\fR \fInum channels\fR
.br
Number of audio capture channels
.TP
\fB-O\fR \fInum channels\fR
.br
Number of midi playback channels
.TP
\fB-I\fR \fInum channels\fR
.br
Number of midi capture channels
.TP
\fB-n\fR \fIperiods\fR
.br
Network latency in JACK periods
.TP
\fB-p\fR \fIport\fR
.br
UDP port that the slave is listening on
.TP
\fB-r\fR \fIreply port\fR
.br
UDP port that we are listening on
.TP
\fB-B\fR \fIbind port\fR
.br
reply port, for use in NAT environments
.TP
\fB-b\fR \fIbitdepth\fR
.br
Set transport to use 16bit or 8bit
.TP
\fB-P\fR \fIkbits\fR
.br
Use Opus encoding with <kbits> per channel
.TP
\fB-m\fR \fImtu\fR
.br
Assume this mtu for the link
.TP
\fB-R\fR \fIN\fR
.br
Redundancy: send out packets N times.
.TP
\fB-e\fR
.br
skip host-to-network endianness conversion
.TP
\fB-N\fR \fIjack name\fR
.br
Reports a different client name to jack
.TP
.TP
\fB-s\fR, \fB--server\fR \fIservername\fR
.br
Connect to the jack server named \fIservername\fR
.TP
\fB-h\fR, \fB--help\fR
.br
Display help/usage message
.TP
\fB-v\fR, \fB--version\fR
.br
Output version information and exit


.SH EXAMPLES

.PP
run a 4 audio channel bidirectional link with one period of latency and no midi channels. Audio data is flowing uncompressed over the wire:
.br
On \fIhostA\fR:
.IP
\fBjackd \-d alsa \fR
.br
\fBjack_netsource \-H hostB -n1 -i4 -o4 -I0 -O0 \fR
.PP
On \fIhostB\fR:
.IP
\fBjackd \-d net \fR

07070100000037000081A400000000000000000000000161E2F7EE00000965000000000000000000000000000000000000002900000000jack-example-tools-1/man/jack_property.0.TH JACK_PROPERTY "1" "@DATE@" "@VERSION@"
.SH NAME
jack_property \- JACK client to list, set and delete metadata information
.SH SYNOPSIS
\fBjack_property\fR -l
.br
\fBjack_property\fR [ -c | -p ] -l \fIidentifier\fR 
.br
\fBjack_property\fR [ -c | -p ] -l \fIidentifier\fR \fIkey\fR
.br
\fBjack_property\fR [ -c | -p ] -s \fIidentifier\fR \fIkey\fR \fIvalue\fR [ \fItype\fR ]
.br
\fBjack_property\fR [ -c | -p ] -d \fIidentifier\fR 
.br
\fBjack_property\fR [ -c | -p ] -d \fIidentifier\fR \fIkey\fR
.br
\fBjack_property\fR -D 
.SH DESCRIPTION
\fBjack_property\fR can be used to list, set and delete any and all metadata associated with the ports
and clients of a JACK server.
.P
There are three main ways to use the command. The \fB-l\fR option is used to list existing metadata. The \fB-s\fR option is used
to set metadata. The \fB-d/-D\fR options are used to delete metadata.
.P
The \fIidentifier\fR is normally a UUID (UUIDs for ports and clients can be shown with jack_lsp(1)). If the \fB-c\fR option is used, then \fIidentifier\fR will
be interpreted as a client name, and its UUID will be looked up internally and used for the relevant metadata operation. If the \fB-p\fR option is used, then \fIidentifier\fR will
be interpreted as a port name and its UUID  will be looked up internally and used for the relevant metadata operation.
.P
The \fIkey\fR is an arbitrary string that identifies the metadata to be operated upon.
.P
The \fIvalue\fR is an arbitrary string that defines the value of the metadata to be created.
.P
The \fItype\fR is an optional MIME type, given as a string. An empty type for a piece of metadata results in it being interpreted as "text/UTF-8". 
.SH OPTIONS
.TP 6
-l
list all metadata currently defined
.TP
-l identifier
list all metadata currently defined for \fIidentifier\fR
.TP
-l identifier key
show the value of the metadata associated with key for \fIidentifier\fR
.TP
-d identifier
deletes all metadata for \fIidentifier\fR
.TP
-d identifier key
deletes the metadata associated with \fIkey\fR for \fIidentifier\fR
.TP
-D
delete all currently defined metadata
.TP
-s identifier key value [ type ]
sets the metadata associated with \fIkey\fR to \fIvalue\fR for \fIidentifer\fR, with its type set to \fItype\fR if given
.TP
-c 
interpret a given identifier as a client name rather than a UUID
.TP 
-p
interpret a given identifier as a port name rather than a UUID



07070100000038000081A400000000000000000000000161E2F7EE00000414000000000000000000000000000000000000002400000000jack-example-tools-1/man/jack_rec.0.TH JACK_REC "1" "@DATE@" "@VERSION@"
.SH NAME
jack_rec \- JACK toolkit client for recording audio
.SH SYNOPSIS
.B jack_rec
\-f filename \-d seconds [ \-b bitdepth ] port1 [ port2 ... ]
.SH DESCRIPTION
.B jack_rec is a basic, but useful, audio recorder that will record
audio from 1 or more JACK ports to a file on disk. The file format is
always RIFF/WAV, with samples stored as signed integers. The sample
bit depth can be selected using the \fI-b\fR option. The file will
have as many channels as there are ports specified on the command line
- each channel will contain the data recorded from one port. The user
should generally specify the duration (in seconds) using the \fI-d\fR
option. If not specified, jack_rec will record until terminated by a
signal (eg. from Ctrl-c).
.PP
This application is not intended to be a heavy duty audio recorder,
and originated as an example client to show how to handle threading
and disk I/O in a JACK client. However, it is a useful, simple
recorder and is included in the JACK toolkit as a result.


07070100000039000081A400000000000000000000000161E2F7EE000000E8000000000000000000000000000000000000002B00000000jack-example-tools-1/man/jack_samplerate.0.TH JACK_SAMPLERATE "1" "@DATE@" "@VERSION@"
.SH NAME
jack_samplerate \- JACK toolkit client to print current samplerate
.SH SYNOPSIS
.B jack_samplerate
.SH DESCRIPTION
.B jack_samplerate prints the current samplerate, and exits.


0707010000003A000081A400000000000000000000000161E2F7EE0000013E000000000000000000000000000000000000002900000000jack-example-tools-1/man/jack_showtime.0.TH JACK_SHOWTIME "1" "@DATE@" "@VERSION@"
.SH NAME
jack_showtime \- The JACK Audio Connection Kit example client
.SH SYNOPSIS
.B jack_showtime
.SH DESCRIPTION
.B jack_showtime
prints the current timebase information to stdout
.SH AUTHOR
Paul Davis
.PP
This manpage was written by Stefan Schwandter <swan@debian.org>

0707010000003B000081A400000000000000000000000161E2F7EE0000022F000000000000000000000000000000000000002E00000000jack-example-tools-1/man/jack_simple_client.0.TH JACK_CONNECT "1" "@DATE@" "@VERSION@"
.SH NAME
jack_simple_client \- The JACK Audio Connection Kit example client
.SH SYNOPSIS
.B jack_simple_client
client-name
.PP
The client-name must be a yet unused client name.
.SH DESCRIPTION
.B jack_simple_client
is an example client for the JACK Audio Connection Kit. It creates two
ports (client-name:input and client-name:output) that pass the data
unmodified.
.SH EXAMPLE
jack_simple_client in_process_test
.SH AUTHOR
Jeremy Hall
.PP
This manpage was written by Robert Jordens <jordens@debian.org> for Debian.

0707010000003C000081A400000000000000000000000161E2F7EE0000018E000000000000000000000000000000000000002A00000000jack-example-tools-1/man/jack_transport.0.TH JACK_TRANSPORT "1" "@DATE@" "@VERSION@"
.SH NAME
jack_transport \- JACK toolkit client for transport control
.SH SYNOPSIS
.B jack_transport
.SH DESCRIPTION
.B jack_transport
is a toolkit client for the JACK Audio Connection Kit. It provides command-line
control over the JACK transport system. Type help at jack_transport's
command prompt to see the available commands.
.SH AUTHOR
Jeremy Hall

0707010000003D000081A400000000000000000000000161E2F7EE000001DC000000000000000000000000000000000000002700000000jack-example-tools-1/man/jack_unload.0.TH JACK_UNLOAD "1" "@DATE@" "@VERSION@"
.SH NAME
jack_unload \- The JACK Audio Connection Kit example client
.SH SYNOPSIS
.B jack_unload 
client-name
.PP
The client-name must be the name of a loaded client that can be unloaded.
.SH DESCRIPTION
.B jack_unload
is the counterpart to 
.B jack_load
and unloads the specified client.
.SH EXAMPLE
.B jack_unload in_process_test
.SH AUTHOR
Jeremy Hall
.PP
This manpage was written by Robert Jordens <jordens@debian.org> for Debian.
0707010000003E000081A400000000000000000000000161E2F7EE00000400000000000000000000000000000000000000002500000000jack-example-tools-1/man/jack_wait.0.TH JACK_WAIT "1" "@DATE@" "@VERSION@"
.SH NAME
jack_wait \- JACK toolkit client to check and wait for existence/exit of jackd.  
.SH SYNOPSIS
\fBjack_wait\fR [ \fI-s\fR | \fI--server\fR servername ] [ \fI-t\fR | \fI--timeout\fR timeout_seconds [ \fI-cqwhv\fR ]
.SH DESCRIPTION
\fBjack_wait\fR When invoked with \fI-c\fR it only checks for the existence of a jack server. When invoked with \fI-w\fR the
program will wait for a jackd to be available.
The \fI-q\fR makes it wait for the jackd to exit.

.SH OPTIONS
.TP
\fB-w\fR, \fB--wait\fR
.br
Wait for jackd to be available.
.TP
\fB-q\fR, \fB--quit\fR
.br
Wait for jackd quit.
.TP
\fB-c\fR, \fB--check\fR
.br
Only check for existence of jackd, and exit.
.TP
\fB-s\fR, \fB--server\fR \fIservername\fR
.br
Connect to the jack server named \fIservername\fR
.TP
\fB-t\fR, \fB--timeout\fR \fItimeout_seconds\fR
.br
Only wait \fItimeout_seconds\fR.
.TP
\fB-h\fR, \fB--help\fR
.br
Display help/usage message
.TP
\fB-v\fR, \fB--version\fR
.br
Output version information and exit


0707010000003F000081A400000000000000000000000161E2F7EE00000311000000000000000000000000000000000000002500000000jack-example-tools-1/man/meson.buildman_pages = [
  'jack_bufsize',
  'jack_connect',
  'jack_disconnect',
  'jack_freewheel',
  'jack_impulse_grabber',
  'jack_iodelay',
  'jack_load',
  'jack_lsp',
  'jack_metro',
  'jack_monitor_client',
  'jack_property',
  'jack_samplerate',
  'jack_showtime',
  'jack_simple_client',
  'jack_transport',
  'jack_unload',
  'jack_wait',
]

if build_alsa_in_out
  man_pages += ['alsa_in', 'alsa_out']
endif
if build_jack_netsource
  man_pages += ['jack_netsource']
endif
if build_jack_rec
  man_pages += ['jack_rec']
endif

if os != 'windows'
  foreach man_page: man_pages
    configure_file(
      configuration: conf_data,
      input: man_page + '.0',
      output: man_page + '.1',
      install_dir: get_option('mandir') + '/man1',
      install: true,
    )
  endforeach
endif
07070100000040000081A400000000000000000000000161E2F7EE0000131C000000000000000000000000000000000000002100000000jack-example-tools-1/meson.buildproject(
  'jack-example-tools',
  ['c', 'cpp'],
  meson_version: '>=0.58.0',
  license: ['GPL2+'],
  version: '1',
)

os = build_machine.system()
cc = meson.get_compiler('c')
lib_m = cc.find_library('m')
lib_rt = cc.find_library('rt')

alsa_required = false
if get_option('alsa_in_out').enabled() or get_option('zalsa').enabled()
  alsa_required = true
endif

libsamplerate_required = false
if get_option('alsa_in_out').enabled() or get_option('jack_netsource').enabled()
  libsamplerate_required = true
endif

dep_jack = dependency('jack')

jack_implementation = ''
jack_implementation = dep_jack.get_variable('jack_implementation')
if jack_implementation == ''
  warning('No compatible jack implementation detected. This may mean conflicting files when installing!')
endif

has_jack1_internal_client = cc.compiles(
  '''
  #include <stdio.h>
  #include <jack/jack.h>
  #include <jack/intclient.h>

  int main (int argc, char *argv[]) {
    const char *client_name;
    jack_client_t *client;
    jack_status_t status;
    jack_intclient_t intclient;

    client_name = "foo";
    client = jack_client_open(client_name, JackNoStartServer, &status);
    jack_internal_client_handle(client, client_name, &status, &intclient);
  }
  '''
)
message('Provides jack1-style jack_internal_client_handle(): ' + has_jack1_internal_client.to_string())

has_jack2_internal_client = cc.compiles(
  '''
  #include <jack/jack.h>
  #include <jack/intclient.h>

  int main (int argc, char *argv[]) {
    const char *client_name;
    jack_client_t *client;
    jack_status_t status;
    jack_intclient_t intclient;

    client_name = "foo";
    client = jack_client_open(client_name, JackNoStartServer, &status);
    intclient = jack_internal_client_handle (client, client_name, &status);
  }
  '''
)
message('Provides jack2-style jack_internal_client_handle(): ' + has_jack2_internal_client.to_string())

lib_jackserver = cc.find_library('jackserver', required: true)
has_jackctl_server_create2 = cc.has_function('jackctl_server_create2', dependencies: lib_jackserver, prefix: '#include <jack/control.h>')

lib_jacknet = cc.find_library('jacknet', required: get_option('jack_net'))

dep_alsa = dependency('alsa', version: '>=1.0.18', required: alsa_required)
dep_opus = dependency('opus', version: '>=0.9.0', required: get_option('opus_support'))
dep_readline = dependency('readline', required: get_option('readline_support'))
dep_samplerate = dependency('samplerate', required: libsamplerate_required)
dep_sndfile = dependency('sndfile', required: get_option('jack_rec'))
dep_threads = dependency('threads')
lib_zita_alsa_pcmi = cc.find_library('zita-alsa-pcmi', required: get_option('zalsa'))
lib_zita_resampler = cc.find_library('zita-resampler', required: get_option('zalsa'))
has_ppoll = cc.has_function('ppoll', prefix: '#define _GNU_SOURCE\n#include <sys/poll.h>')

build_alsa_in_out = false
if get_option('alsa_in_out').enabled() or (
  get_option('alsa_in_out').auto() and dep_alsa.found() and dep_samplerate.found()
)
  build_alsa_in_out = true
endif

build_jack_net = false
if get_option('jack_net').enabled() or (get_option('jack_net').auto() and lib_jacknet.found())
  build_jack_net = true
endif

build_jack_netsource = false
if get_option('jack_netsource').enabled() or (get_option('jack_netsource').auto() and dep_samplerate.found())
  build_jack_netsource = true
endif

opus_support = false
if get_option('opus_support').enabled() or (get_option('opus_support').auto() and dep_opus.found())
  opus_support = true
endif

readline_support = false
if get_option('readline_support').enabled() or (get_option('readline_support').auto() and dep_readline.found())
  readline_support = true
endif

build_jack_rec = false
if get_option('jack_rec').enabled() or (get_option('jack_rec').auto() and dep_sndfile.found())
  build_jack_rec = true
endif

build_zalsa = false
if get_option('zalsa').enabled() or (
  get_option('zalsa').auto() and dep_alsa.found() and lib_zita_alsa_pcmi.found() and lib_zita_resampler.found()
)
  build_zalsa = true
endif


message('Build alsa_in and alsa_out executables: ' + build_alsa_in_out.to_string())
message('Build jack_net_master and jack_net_slave executables: ' + build_jack_net.to_string())
message('Build jack_netsource executable: ' + build_jack_netsource.to_string())
if build_jack_netsource
  message('Build jack_netsource with opus support: ' + opus_support.to_string())
endif
message('Build jack_rec executable: ' + build_jack_rec.to_string())
message('Build jack_transport with readline support: ' + readline_support.to_string())
message('Build ZALSA internal clients: ' + build_zalsa.to_string())

conf_data = configuration_data()
conf_data.set('VERSION', meson.project_version())
conf_data.set('DATE', '2022')

c_args_common = [
  '-D__PROJECT_VERSION__="@0@"'.format(conf_data.get('VERSION')),
]

subdir('tools')
subdir('example-clients')
subdir('man')
07070100000041000081A400000000000000000000000161E2F7EE0000038D000000000000000000000000000000000000002700000000jack-example-tools-1/meson_options.txtoption('alsa_in_out', type: 'feature', value: 'auto', description: 'Build the alsa_in and alsa_out executables (default: auto)')
option('jack_net', type: 'feature', value: 'auto', description: 'Build the jack_net_master and jack_net_slave executables (default: auto)')
option('jack_netsource', type: 'feature', value: 'auto', description: 'Build the jack_netsource executable (default: auto)')
option('jack_rec', type: 'feature', value: 'auto', description: 'Build the jack_rec executable (default: auto)')
option('opus_support', type: 'feature', value: 'auto', description: 'Build the jack_netsource executable with opus support (default: auto)')
option('readline_support', type: 'feature', value: 'auto', description: 'Build the jack_transport executable with readline support (default: auto)')
option('zalsa', type: 'feature', value: 'auto', description: 'Build the ZALSA internal client (default: auto)')
07070100000042000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000001D00000000jack-example-tools-1/scripts07070100000043000081ED00000000000000000000000161E2F7EE00000145000000000000000000000000000000000000003200000000jack-example-tools-1/scripts/meson_create_symlink#!/usr/bin/env sh
#
# Script to create a symlink for an arbitrary file ($2) in a directory ($1)
# below $MESON_INSTALL_DESTDIR_PREFIX of a specific name ($3).
#
# E.g. `meson_create_symlink bin test2 test` creates:
# $MESON_INSTALL_DESTDIR_PREFIX/bin/test2 -> test

set -eu

ln -sv "$2" "$MESON_INSTALL_DESTDIR_PREFIX/$1/$3"
07070100000044000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000001B00000000jack-example-tools-1/tools07070100000045000081A400000000000000000000000161E2F7EE000009AD000000000000000000000000000000000000002300000000jack-example-tools-1/tools/alias.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>

#include <jack/jack.h>

char * my_name;

void
show_version (void)
{
	fprintf (stderr, "%s: JACK example tools version %s\n", my_name, __PROJECT_VERSION__);
}

void
show_usage (void)
{
	show_version ();
	fprintf (stderr, "\nUsage: %s [options] portname alias\n", my_name);
	fprintf (stderr, "List active Jack ports, and optionally display extra information.\n\n");
	fprintf (stderr, "Display options:\n");
	fprintf (stderr, "        -u, --unalias         remove `alias' as an alias for `port'\n");
	fprintf (stderr, "        -h, --help            Display this help message\n");
	fprintf (stderr, "        --version             Output version information and exit\n\n");
	fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

int
main (int argc, char *argv[])
{
	jack_client_t *client;
	jack_status_t status;
	char* portname;
	char* alias;
	int unset = 0;
	int ret;
	int c;
	int option_index;
	extern int optind;
	jack_port_t* port;
	
	struct option long_options[] = {
		{ "unalias", 0, 0, 'u' },
		{ "help", 0, 0, 'h' },
		{ "version", 0, 0, 'v' },
		{ 0, 0, 0, 0 }
	};

	if (argc < 3) {
		show_usage ();
		return 1;
	}

	my_name = strrchr(argv[0], '/');
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	while ((c = getopt_long (argc, argv, "uhv", long_options, &option_index)) >= 0) {
		switch (c) {
		case 'u':
			unset = 1;
			break;
		case 'h':
			show_usage ();
			return 1;
			break;
		case 'v':
			show_version ();
			return 1;
			break;
		default:
			show_usage ();
			return 1;
			break;
		}
	}

	portname = argv[optind++];
	alias = argv[optind];

	/* Open a client connection to the JACK server.  Starting a
	 * new server only to list its ports seems pointless, so we
	 * specify JackNoStartServer. */
	//JOQ: need a new server name option

	client = jack_client_open ("lsp", JackNoStartServer, &status);

	if (client == NULL) {
		if (status & JackServerFailed) {
			fprintf (stderr, "JACK server not running\n");
		} else {
			fprintf (stderr, "jack_client_open() failed, "
				 "status = 0x%2.0x\n", status);
		}
		return 1;
	}

	if ((port = jack_port_by_name (client, portname)) == 0) {
		fprintf (stderr, "No port named \"%s\"\n", portname);
		return 1;
	}

	if (!unset) {
		ret = jack_port_set_alias (port, alias);
	} else {
		ret = jack_port_unset_alias (port, alias);
	}

	jack_client_close (client);

	return ret;
	
}
07070100000046000081A400000000000000000000000161E2F7EE00005C89000000000000000000000000000000000000002500000000jack-example-tools-1/tools/alsa_in.c/** @file simple_client.c
 *
 * @brief This simple client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include <math.h>

#include <jack/jack.h>
#include <jack/jslist.h>
#include "memops.h"

#include "alsa/asoundlib.h"

#include <samplerate.h>

// Here are the lists of the jack ports...

JSList	   *capture_ports = NULL;
JSList	   *capture_srcs = NULL;
JSList	   *playback_ports = NULL;
JSList	   *playback_srcs = NULL;
jack_client_t *client;

snd_pcm_t *alsa_handle;

int jack_sample_rate;
int jack_buffer_size;

int quit = 0;
double resample_mean = 1.0;
double static_resample_factor = 1.0;
double resample_lower_limit = 0.25;
double resample_upper_limit = 4.0;

double *offset_array;
double *window_array;
int offset_differential_index = 0;

double offset_integral = 0;

// ------------------------------------------------------ commandline parameters

const char* alsa_device = "hw:0";
int sample_rate = 0;				 /* stream rate */
int num_channels = 2;				 /* count of channels */
int period_size = 1024;
int num_periods = 2;

int target_delay = 0;	    /* the delay which the program should try to approach. */
int max_diff = 0;	    /* the diff value, when a hard readpointer skip should occur */
int catch_factor = 100000;
int catch_factor2 = 10000;
double pclamp = 15.0;
double controlquant = 10000.0;
int smooth_size = 256;
int good_window=0;
int verbose = 0;
int instrument = 0;
int samplerate_quality = 2;

// Debug stuff:

volatile float output_resampling_factor = 1.0;
volatile int output_new_delay = 0;
volatile float output_offset = 0.0;
volatile float output_integral = 0.0;
volatile float output_diff = 0.0;

snd_pcm_uframes_t real_buffer_size;
snd_pcm_uframes_t real_period_size;

// buffers

char *tmpbuf;
char *outbuf;
float *resampbuf;

// format selection, and corresponding functions from memops in a nice set of structs.

typedef struct alsa_format {
	snd_pcm_format_t format_id;
	size_t sample_size;
	void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
	void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
	const char *name;
} alsa_format_t;

alsa_format_t formats[] = {
	{ SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" },
	{ SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" },
	{ SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" },
	{ SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" },
	{ SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" }
#ifdef __ANDROID__
	,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" }
#endif
};
#define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
int format=0;

// Alsa stuff... i don't want to touch this bullshit in the next years.... please...

static int xrun_recovery(snd_pcm_t *handle, int err) {
//	printf( "xrun !!!.... %d\n", err );
	if (err == -EPIPE) {	/* under-run */
		err = snd_pcm_prepare(handle);
		if (err < 0)
			printf("Can't recover from underrun, prepare failed: %s\n", snd_strerror(err));
		return 0;
	} else if (err == -ESTRPIPE) {
		while ((err = snd_pcm_resume(handle)) == -EAGAIN)
			usleep(100);	/* wait until the suspend flag is released */
		if (err < 0) {
			err = snd_pcm_prepare(handle);
			if (err < 0)
				printf("Can't recover from suspend, prepare failed: %s\n", snd_strerror(err));
		}
		return 0;
	}
	return err;
}

static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
{
#ifdef __ANDROID__
	format = 5;
	snd_pcm_hw_params_set_format(handle, params, formats[format].format_id);
	return 0;
#else
	int i;
	int err;

	for( i=0; i<NUMFORMATS; i++ ) {
		/* set the sample format */
		err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id);
		if (err == 0) {
			format = i;
			return 0;
		}
	}

	return err;
#endif
}

static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
	int err, dir=0;
	unsigned int buffer_time;
	unsigned int period_time;
	unsigned int rrate;
	unsigned int rchannels;

	/* choose all parameters */
	err = snd_pcm_hw_params_any(handle, params);
	if (err < 0) {
		printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
		return err;
	}
	/* set the interleaved read/write format */
	err = snd_pcm_hw_params_set_access(handle, params, access);
	if (err < 0) {
		printf("Access type not available for playback: %s\n", snd_strerror(err));
		return err;
	}

	/* set the sample format */
	err = set_hwformat(handle, params);
	if (err < 0) {
		printf("Sample format not available for playback: %s\n", snd_strerror(err));
		return err;
	}
	/* set the count of channels */
	rchannels = channels;
	err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels);
	if (err < 0) {
		printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err));
		return err;
	}
	if (rchannels != channels) {
		printf("WARNING: channel count does not match (requested %d got %d)\n", channels, rchannels);
		num_channels = rchannels;
	}
	/* set the stream rate */
	rrate = rate;
	err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
	if (err < 0) {
		printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
		return err;
	}
	if (rrate != rate) {
		printf("WARNING: Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate);
		sample_rate = rrate;
	}
	/* set the buffer time */

	buffer_time = 1000000*(uint64_t)period*nperiods/rate;
	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
	if (err < 0) {
		printf("Unable to set buffer time %i for playback: %s\n",  1000000*period*nperiods/rate, snd_strerror(err));
		return err;
	}
	err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size );
	if (err < 0) {
		printf("Unable to get buffer size back: %s\n", snd_strerror(err));
		return err;
	}
	if( real_buffer_size != nperiods * period ) {
		printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size );
	}
	/* set the period time */
	period_time = 1000000*(uint64_t)period/rate;
	err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
	if (err < 0) {
		printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err));
		return err;
	}
	err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL );
	if (err < 0) {
		printf("Unable to get period size back: %s\n", snd_strerror(err));
		return err;
	}
	if( real_period_size != period ) {
		printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size );
	}
	/* write the parameters to device */
	err = snd_pcm_hw_params(handle, params);
	if (err < 0) {
		printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}

static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period) {
	int err;

	/* get the current swparams */
	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0) {
		printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* start the transfer when the buffer is full */
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* allow the transfer when at least period_size samples can be processed */
	err = snd_pcm_sw_params_set_avail_min(handle, swparams, 2*period );
	if (err < 0) {
		printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* write the parameters to the playback device */
	err = snd_pcm_sw_params(handle, swparams);
	if (err < 0) {
		printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}

// ok... i only need this function to communicate with the alsa bloat api...

static snd_pcm_t *open_audiofd( const char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
	int err;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;

	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_sw_params_alloca(&swparams);

	if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
		printf("Capture open error: %s\n", snd_strerror(err));
		return NULL;
	}

	if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
		printf("Setting of hwparams failed: %s\n", snd_strerror(err));
		return NULL;
	}
	if ((err = set_swparams(handle, swparams, period)) < 0) {
		printf("Setting of swparams failed: %s\n", snd_strerror(err));
		return NULL;
	}

	snd_pcm_start( handle );
	snd_pcm_wait( handle, 200 );

	return handle;
}

double hann( double x )
{
	return 0.5 * (1.0 - cos( 2*M_PI * x ) );
}

/**
 * The freewheel callback.
 */
void freewheel (int freewheel_starting, void* ignored_arg) {
	if( freewheel_starting ) {
		snd_pcm_close( alsa_handle );
		alsa_handle = 0;
		// reset resampling parameters 
		resample_mean = 1.0;
		static_resample_factor = 1.0;
		resample_lower_limit = 0.25;
		resample_upper_limit = 4.0;
		offset_differential_index = 0;
		offset_integral = 0;
	} else {
		alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods);
		if( alsa_handle == 0 )
			exit(20);
	}
}

/**
 * The process callback for this JACK application.
 * It is called by JACK at the appropriate times.
 */
int process (jack_nframes_t nframes, void *arg) {

	if (alsa_handle == 0) {
		JSList *node = capture_ports;

		while ( node != NULL)
		{
			jack_port_t *port = (jack_port_t *) node->data;
			float *buf = jack_port_get_buffer (port, nframes);

			memset(buf, 0, sizeof(float)*nframes);

			node = jack_slist_next (node);
		}

		return 0;
	}

	int rlen;
	int err;
	snd_pcm_sframes_t delay = target_delay;
	int put_back_samples=0;
	int i;

	delay = snd_pcm_avail( alsa_handle );

	delay -= round( jack_frames_since_cycle_start( client ) * static_resample_factor );
	// Do it the hard way.
	// this is for compensating xruns etc...

	if( delay > (target_delay+max_diff) ) {

		output_new_delay = (int) delay;

		while ((delay-target_delay) > 0) {
			snd_pcm_uframes_t to_read = ((delay-target_delay) > 512) ? 512 : (delay-target_delay);
			snd_pcm_readi( alsa_handle, tmpbuf, to_read );
			delay -= to_read;
		}

		delay = target_delay;

		// Set the resample_rate... we need to adjust the offset integral, to do this.
		// first look at the PI controller, this code is just a special case, which should never execute once
		// everything is swung in. 
		offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
		// Also clear the array. we are beginning a new control cycle.
		for( i=0; i<smooth_size; i++ )
			offset_array[i] = 0.0;
	}
	if( delay < (target_delay-max_diff) ) {
		snd_pcm_rewind( alsa_handle, target_delay - delay );
		output_new_delay = (int) delay;
		delay = target_delay;

		// Set the resample_rate... we need to adjust the offset integral, to do this.
		offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
		// Also clear the array. we are beginning a new control cycle.
		for( i=0; i<smooth_size; i++ )
			offset_array[i] = 0.0;
	}
	/* ok... now we should have target_delay +- max_diff on the alsa side.
	 *
	 * calculate the number of frames, we want to get.
	 */

	double offset = delay - target_delay;

	// Save offset.
	offset_array[(offset_differential_index++)% smooth_size ] = offset;

	// Build the mean of the windowed offset array
	// basically fir lowpassing.
	double smooth_offset = 0.0;
	for( i=0; i<smooth_size; i++ )
		smooth_offset +=
			offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i];
	smooth_offset /= (double) smooth_size;

	// this is the integral of the smoothed_offset
	offset_integral += smooth_offset;

	// Clamp offset.
	// the smooth offset still contains unwanted noise
	// which would go straight onto the resample coeff.
	// it only used in the P component and the I component is used for the fine tuning anyways.
	if( fabs( smooth_offset ) < pclamp )
		smooth_offset = 0.0;

	// ok. now this is the PI controller. 
	// u(t) = K * ( e(t) + 1/T \int e(t') dt' )
	// K = 1/catch_factor and T = catch_factor2
	double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2;

	// now quantize this value around resample_mean, so that the noise which is in the integral component doesn't hurt.
	current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean;

	// Output "instrumentatio" gonna change that to real instrumentation in a few.
	output_resampling_factor = (float) current_resample_factor;
	output_diff = (float) smooth_offset;
	output_integral = (float) offset_integral;
	output_offset = (float) offset;

	// Clamp a bit.
	if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit;
	if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit;

	// Now Calculate how many samples we need.
	rlen = ceil( ((double)nframes) * current_resample_factor )+2;
	assert( rlen > 2 );

	// Calculate resample_mean so we can init ourselves to saner values.
	resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor;

	// get the data...
again:
	err = snd_pcm_readi(alsa_handle, outbuf, rlen);
	if( err < 0 ) {
		printf( "err = %d\n", err );
		if (xrun_recovery(alsa_handle, err) < 0) {
			//printf("Write error: %s\n", snd_strerror(err));
			//exit(EXIT_FAILURE);
		}
		goto again;
	}
	if( err != rlen ) {
		//printf( "read = %d\n", rlen );
	}

	/*
	 * render jack ports to the outbuf...
	 */

	int chn = 0;
	JSList *node = capture_ports;
	JSList *src_node = capture_srcs;
	SRC_DATA src;

	while ( node != NULL)
	{
		jack_port_t *port = (jack_port_t *) node->data;
		float *buf = jack_port_get_buffer (port, nframes);

		SRC_STATE *src_state = src_node->data;

		formats[format].soundcard_to_jack( resampbuf, outbuf + format[formats].sample_size * chn, rlen, num_channels*format[formats].sample_size );

		src.data_in = resampbuf;
		src.input_frames = rlen;

		src.data_out = buf;
		src.output_frames = nframes;
		src.end_of_input = 0;

		src.src_ratio = current_resample_factor;

		src_process( src_state, &src );

		put_back_samples = rlen-src.input_frames_used;

		src_node = jack_slist_next (src_node);
		node = jack_slist_next (node);
		chn++;
	}

	// Put back the samples libsamplerate did not consume.
	//printf( "putback = %d\n", put_back_samples );
	snd_pcm_rewind( alsa_handle, put_back_samples );

	return 0;
}

/**
 * the latency callback.
 * sets up the latencies on the ports.
 */

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
	jack_latency_range_t range;
	JSList *node;

	range.min = range.max = round(target_delay / static_resample_factor);

	if (mode == JackCaptureLatency) {
		for (node = capture_ports; node; node = jack_slist_next (node)) {
			jack_port_t *port = node->data;
			jack_port_set_latency_range (port, mode, &range);
		}
	} else {
		for (node = playback_ports; node; node = jack_slist_next (node)) {
			jack_port_t *port = node->data;
			jack_port_set_latency_range (port, mode, &range);
		}
	}
}


/**
 * Allocate the necessary jack ports...
 */

void alloc_ports( int n_capture, int n_playback ) {

	int port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
	int chn;
	jack_port_t *port;
	char buf[32];

	capture_ports = NULL;
	for (chn = 0; chn < n_capture; chn++)
	{
		snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1);

		port = jack_port_register (client, buf,
			JACK_DEFAULT_AUDIO_TYPE,
			port_flags, 0);

		if (!port)
		{
			printf( "jacknet_client: cannot register port for %s", buf);
			break;
		}

		capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) );
		capture_ports = jack_slist_append (capture_ports, port);
	}

	port_flags = JackPortIsInput;

	playback_ports = NULL;
	for (chn = 0; chn < n_playback; chn++)
	{
		snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1);

		port = jack_port_register (client, buf,
			JACK_DEFAULT_AUDIO_TYPE,
			port_flags, 0);

		if (!port)
		{
			printf( "jacknet_client: cannot register port for %s", buf);
			break;
		}

		playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) );
		playback_ports = jack_slist_append (playback_ports, port);
	}
}

/**
 * This is the shutdown callback for this JACK application.
 * It is called by JACK if the server ever shuts down or
 * decides to disconnect the client.
 */

void jack_shutdown (void *arg) {

	exit (1);
}

/**
 * be user friendly.
 * be user friendly.
 * be user friendly.
 */

void printUsage() {
fprintf(stderr, "usage: alsa_out [options]\n"
		"\n"
		"  -j <jack name> - client name\n"
		"  -S <server name> - server to connect\n"
		"  -d <alsa_device> \n"
		"  -c <channels> \n"
		"  -p <period_size> \n"
		"  -n <num_period> \n"
		"  -r <sample_rate> \n"
		"  -q <sample_rate quality [0..4]\n"
		"  -m <max_diff> \n"
		"  -t <target_delay> \n"
		"  -i  turns on instrumentation\n"
		"  -v  turns on printouts\n"
		"\n");
}


/**
 * the main function....
 */

void
sigterm_handler( int signal )
{
	quit = 1;
}


int main (int argc, char *argv[]) {
	char jack_name[30] = "alsa_in";
	int jack_opts = 0;
	char *server_name = NULL;

	extern char *optarg;
	extern int optind, optopt;
	int errflg=0;
	int c;

	while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:S:")) != -1) {
		switch(c) {
		case 'j':
			strcpy(jack_name,optarg);
			break;
		case 'r':
			sample_rate = atoi(optarg);
			break;
		case 'c':
			num_channels = atoi(optarg);
			break;
		case 'p':
			period_size = atoi(optarg);
			break;
		case 'n':
			num_periods = atoi(optarg);
			break;
		case 'd':
			alsa_device = strdup (optarg);
			break;
		case 't':
			target_delay = atoi(optarg);
			break;
		case 'q':
			samplerate_quality = atoi(optarg);
			break;
		case 'm':
			max_diff = atoi(optarg);
			break;
		case 'f':
			catch_factor = atoi(optarg);
			break;
		case 'F':
			catch_factor2 = atoi(optarg);
			break;
		case 'C':
			pclamp = (double) atoi(optarg);
			break;
		case 'Q':
			controlquant = (double) atoi(optarg);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'i':
			instrument = 1;
			break;
		case 's':
			smooth_size = atoi(optarg);
			break;
		case 'S':
			server_name = optarg;
			jack_opts |= JackServerName;
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n", optopt);
			errflg++;
			break;
		case '?':
			fprintf(stderr,
				"Unrecognized option: -%c\n", optopt);
			errflg++;
		}
	}
	if (errflg) {
		printUsage();
		exit(2);
	}

	if( (samplerate_quality < 0) || (samplerate_quality > 4) ) {
		fprintf (stderr, "invalid samplerate quality\n");
		return 1;
	}
	if ((client = jack_client_open (jack_name, jack_opts, NULL, server_name)) == 0) {
		fprintf (stderr, "jack server not running?\n");
		return 1;
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	   */

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `freewheel()' whenever
	   freewheel mode changes.
	   */

	jack_set_freewheel_callback (client, freewheel, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	   */

	jack_on_shutdown (client, jack_shutdown, 0);

	if (jack_set_latency_callback)
		jack_set_latency_callback (client, latency_cb, 0);

	// get jack sample_rate

	jack_sample_rate = jack_get_sample_rate( client );

	if( !sample_rate )
		sample_rate = jack_sample_rate;

	// now open the alsa fd...
	alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods);
	if( alsa_handle == 0 )
		exit(20);

	printf( "selected sample format: %s\n", formats[format].name );

	static_resample_factor =  (double) sample_rate / (double) jack_sample_rate;
	resample_lower_limit = static_resample_factor * 0.25;
	resample_upper_limit = static_resample_factor * 4.0;
	resample_mean = static_resample_factor;

	offset_array = malloc( sizeof(double) * smooth_size );
	if( offset_array == NULL ) {
		fprintf( stderr, "no memory for offset_array !!!\n" );
		exit(20);
	}
	window_array = malloc( sizeof(double) * smooth_size );
	if( window_array == NULL ) {
		fprintf( stderr, "no memory for window_array !!!\n" );
		exit(20);
	}
	int i;
	for( i=0; i<smooth_size; i++ ) {
		offset_array[i] = 0.0;
		window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) );
	}

	jack_buffer_size = jack_get_buffer_size( client );
	// Setup target delay and max_diff for the normal user, who does not play with them...
	if( !target_delay ) 
		target_delay = (num_periods*period_size / 2) + jack_buffer_size/2;

	if( !max_diff )
		max_diff = num_periods*period_size - target_delay ;	

	if( max_diff > target_delay ) {
		fprintf( stderr, "target_delay (%d) can not be smaller than max_diff(%d)\n", target_delay, max_diff );
		exit(20);
	}
	if( (target_delay+max_diff) > (num_periods*period_size) ) {
		fprintf( stderr, "target_delay+max_diff (%d) can not be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size );
		exit(20);
	}
	// alloc input ports, which are blasted out to alsa...
	alloc_ports( num_channels, 0 );

	outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels );
	resampbuf = malloc( num_periods * period_size * sizeof( float ) );
	tmpbuf = malloc( 512 * formats[format].sample_size * num_channels );

	if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL))
	{
		fprintf( stderr, "no memory for buffers.\n" );
		exit(20);
	}

	memset( tmpbuf, 0, 512 * formats[format].sample_size * num_channels);

	/* tell the JACK server that we are ready to roll */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	signal( SIGTERM, sigterm_handler );
	signal( SIGINT, sigterm_handler );

	if( verbose ) {
		while(!quit) {
			usleep(500000);
			if( output_new_delay ) {
				printf( "delay = %d\n", output_new_delay );
				output_new_delay = 0;
			}
			printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset );
		}
	} else if( instrument ) {
		printf( "# n\tresamp\tdiff\toffseti\tintegral\n");
		int n=0;
		while(!quit) {
			usleep(1000);
			printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral );
		}
	} else {
		while(!quit)
		{
			usleep(500000);
			if( output_new_delay ) {
				printf( "delay = %d\n", output_new_delay );
				output_new_delay = 0;
			}
		}
	}

	jack_deactivate( client );
	jack_client_close (client);
	exit (0);
}
07070100000047000081A400000000000000000000000161E2F7EE00005D52000000000000000000000000000000000000002600000000jack-example-tools-1/tools/alsa_out.c/** @file simple_client.c
 *
 * @brief This simple client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <alloca.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include <math.h>

#include <jack/jack.h>
#include <jack/jslist.h>
#include "memops.h"

#include "alsa/asoundlib.h"

#include <samplerate.h>

// Here are the lists of the jack ports...

JSList	   *capture_ports = NULL;
JSList	   *capture_srcs = NULL;
JSList	   *playback_ports = NULL;
JSList	   *playback_srcs = NULL;
jack_client_t *client;

snd_pcm_t *alsa_handle;

int jack_sample_rate;
int jack_buffer_size;

int quit = 0;
double resample_mean = 1.0;
double static_resample_factor = 1.0;
double resample_lower_limit = 0.25;
double resample_upper_limit = 4.0;

double *offset_array;
double *window_array;
int offset_differential_index = 0;

double offset_integral = 0;

// ------------------------------------------------------ commandline parameters

const char* alsa_device = "hw:0";
int sample_rate = 0;				 /* stream rate */
int num_channels = 2;				 /* count of channels */
int period_size = 1024;
int num_periods = 2;

int target_delay = 0;	    /* the delay which the program should try to approach. */
int max_diff = 0;	    /* the diff value, when a hard readpointer skip should occur */
int catch_factor = 100000;
int catch_factor2 = 10000;
double pclamp = 15.0;
double controlquant = 10000.0;
int smooth_size = 256;
int good_window=0;
int verbose = 0;
int instrument = 0;
int samplerate_quality = 2;

// Debug stuff:

volatile float output_resampling_factor = 1.0;
volatile int output_new_delay = 0;
volatile float output_offset = 0.0;
volatile float output_integral = 0.0;
volatile float output_diff = 0.0;

snd_pcm_uframes_t real_buffer_size;
snd_pcm_uframes_t real_period_size;

// buffers

char *tmpbuf;
char *outbuf;
float *resampbuf;

// format selection, and corresponding functions from memops in a nice set of structs.

typedef struct alsa_format {
	snd_pcm_format_t format_id;
	size_t sample_size;
	void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
	void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
	const char *name;
} alsa_format_t;

alsa_format_t formats[] = {
	{ SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" },
	{ SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" },
	{ SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" },
	{ SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" },
	{ SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" }
#ifdef __ANDROID__
	,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" }
#endif
};
#define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
int format=0;

// Alsa stuff... i don't want to touch this bullshit in the next years.... please...

static int xrun_recovery(snd_pcm_t *handle, int err) {
//	printf( "xrun !!!.... %d\n", err );
	if (err == -EPIPE) {	/* under-run */
		err = snd_pcm_prepare(handle);
		if (err < 0)
			printf("Can't recover from underrun, prepare failed: %s\n", snd_strerror(err));
		return 0;
	} else if (err == -ESTRPIPE) {
		while ((err = snd_pcm_resume(handle)) == -EAGAIN)
			usleep(100);	/* wait until the suspend flag is released */
		if (err < 0) {
			err = snd_pcm_prepare(handle);
			if (err < 0)
				printf("Can't recover from suspend, prepare failed: %s\n", snd_strerror(err));
		}
		return 0;
	}
	return err;
}

static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params )
{
#ifdef __ANDROID__
	format = 5;
	snd_pcm_hw_params_set_format(handle, params, formats[format].format_id);
	return 0;
#else
	int i;
	int err;

	for( i=0; i<NUMFORMATS; i++ ) {
		/* set the sample format */
		err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id);
		if (err == 0) {
			format = i;
			return 0;
		}
	}

	return err;
#endif
}

static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
	int err, dir=0;
	unsigned int buffer_time;
	unsigned int period_time;
	unsigned int rrate;
	unsigned int rchannels;

	/* choose all parameters */
	err = snd_pcm_hw_params_any(handle, params);
	if (err < 0) {
		printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
		return err;
	}
	/* set the interleaved read/write format */
	err = snd_pcm_hw_params_set_access(handle, params, access);
	if (err < 0) {
		printf("Access type not available for playback: %s\n", snd_strerror(err));
		return err;
	}

	/* set the sample format */
	err = set_hwformat(handle, params);
	if (err < 0) {
		printf("Sample format not available for playback: %s\n", snd_strerror(err));
		return err;
	}
	/* set the count of channels */
	rchannels = channels;
	err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels);
	if (err < 0) {
		printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err));
		return err;
	}
	if (rchannels != channels) {
		printf("WARNING: channel count does not match (requested %d got %d)\n", channels, rchannels);
		num_channels = rchannels;
	}
	/* set the stream rate */
	rrate = rate;
	err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
	if (err < 0) {
		printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
		return err;
	}
	if (rrate != rate) {
		printf("WARNING: Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate);
		sample_rate = rrate;
	}
	/* set the buffer time */

	buffer_time = 1000000*(uint64_t)period*nperiods/rate;
	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
	if (err < 0) {
		printf("Unable to set buffer time %i for playback: %s\n",  1000000*period*nperiods/rate, snd_strerror(err));
		return err;
	}
	err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size );
	if (err < 0) {
		printf("Unable to get buffer size back: %s\n", snd_strerror(err));
		return err;
	}
	if( real_buffer_size != nperiods * period ) {
		printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size );
	}
	/* set the period time */
	period_time = 1000000*(uint64_t)period/rate;
	err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
	if (err < 0) {
		printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err));
		return err;
	}
	err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL );
	if (err < 0) {
		printf("Unable to get period size back: %s\n", snd_strerror(err));
		return err;
	}
	if( real_period_size != period ) {
		printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size );
	}
	/* write the parameters to device */
	err = snd_pcm_hw_params(handle, params);
	if (err < 0) {
		printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}

static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period, int nperiods) {
	int err;

	/* get the current swparams */
	err = snd_pcm_sw_params_current(handle, swparams);
	if (err < 0) {
		printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* start the transfer when the buffer is full */
	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
	if (err < 0) {
		printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* allow the transfer when at least period_size samples can be processed */
	err = snd_pcm_sw_params_set_avail_min(handle, swparams, 1 );
	if (err < 0) {
		printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
		return err;
	}
	/* write the parameters to the playback device */
	err = snd_pcm_sw_params(handle, swparams);
	if (err < 0) {
		printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
		return err;
	}
	return 0;
}

// ok... i only need this function to communicate with the alsa bloat api...

static snd_pcm_t *open_audiofd( const char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
	int err;
	snd_pcm_t *handle;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;

	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_sw_params_alloca(&swparams);

	if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
		printf("Capture open error: %s\n", snd_strerror(err));
		return NULL;
	}

	if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
		printf("Setting of hwparams failed: %s\n", snd_strerror(err));
		return NULL;
	}
	if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) {
		printf("Setting of swparams failed: %s\n", snd_strerror(err));
		return NULL;
	}

	//snd_pcm_start( handle );
	//snd_pcm_wait( handle, 200 );
	int num_null_samples = nperiods * period * channels;
	char *tmp = alloca( num_null_samples * formats[format].sample_size ); 
	memset( tmp, 0, num_null_samples * formats[format].sample_size );
	snd_pcm_writei( handle, tmp, num_null_samples );

	return handle;
}

double hann( double x )
{
	return 0.5 * (1.0 - cos( 2*M_PI * x ) );
}

/**
 * The freewheel callback.
 */
void freewheel (int freewheel_starting, void* ignored_arg) {
	if( freewheel_starting ) {
		snd_pcm_close( alsa_handle );
		alsa_handle = 0;
		// reset resampling parameters 
		resample_mean = 1.0;
		static_resample_factor = 1.0;
		resample_lower_limit = 0.25;
		resample_upper_limit = 4.0;
		offset_differential_index = 0;
		offset_integral = 0;
	} else {
		alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods);
		if( alsa_handle == 0 )
			exit(20);
	}
}

/**
 * The process callback for this JACK application.
 * It is called by JACK at the appropriate times.
 */
int process (jack_nframes_t nframes, void *arg) {

	if (alsa_handle == 0) {
		JSList *node = playback_ports;

		while ( node != NULL)
		{
			jack_port_t *port = (jack_port_t *) node->data;
			float *buf = jack_port_get_buffer (port, nframes);

			memset(buf, 0, sizeof(float)*nframes);

			node = jack_slist_next (node);
		}

		return 0;
	}

	int rlen;
	int err;
	snd_pcm_sframes_t delay = target_delay;
	int i;

	delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ;

	delay -= round( jack_frames_since_cycle_start( client ) * static_resample_factor );
	// Do it the hard way.
	// this is for compensating xruns etc...

	if( delay > (target_delay+max_diff) ) {
		snd_pcm_rewind( alsa_handle, delay - target_delay );
		output_new_delay = (int) delay;

		delay = target_delay;

		// Set the resample_rate... we need to adjust the offset integral, to do this.
		// first look at the PI controller, this code is just a special case, which should never execute once
		// everything is swung in. 
		offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
		// Also clear the array. we are beginning a new control cycle.
		for( i=0; i<smooth_size; i++ )
			offset_array[i] = 0.0;
	}
	if( delay < (target_delay-max_diff) ) {

		output_new_delay = (int) delay;

		while ((target_delay-delay) > 0) {
			snd_pcm_uframes_t to_write = ((target_delay-delay) > 512) ? 512 : (target_delay-delay);
			snd_pcm_writei( alsa_handle, tmpbuf, to_write );
			delay += to_write;
		}

		delay = target_delay;

		// Set the resample_rate... we need to adjust the offset integral, to do this.
		offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2;
		// Also clear the array. we are beginning a new control cycle.
		for( i=0; i<smooth_size; i++ )
			offset_array[i] = 0.0;
	}
	/* ok... now we should have target_delay +- max_diff on the alsa side.
	 *
	 * calculate the number of frames, we want to get.
	 */

	double offset = delay - target_delay;

	// Save offset.
	offset_array[(offset_differential_index++)% smooth_size ] = offset;

	// Build the mean of the windowed offset array
	// basically fir lowpassing.
	double smooth_offset = 0.0;
	for( i=0; i<smooth_size; i++ )
		smooth_offset +=
			offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i];
	smooth_offset /= (double) smooth_size;

	// this is the integral of the smoothed_offset
	offset_integral += smooth_offset;

	// Clamp offset.
	// the smooth offset still contains unwanted noise
	// which would go straight onto the resample coeff.
	// it only used in the P component and the I component is used for the fine tuning anyways.
	if( fabs( smooth_offset ) < pclamp )
		smooth_offset = 0.0;

	// ok. now this is the PI controller. 
	// u(t) = K * ( e(t) + 1/T \int e(t') dt' )
	// K = 1/catch_factor and T = catch_factor2
	double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2;

	// now quantize this value around resample_mean, so that the noise which is in the integral component doesn't hurt.
	current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean;

	// Output "instrumentatio" gonna change that to real instrumentation in a few.
	output_resampling_factor = (float) current_resample_factor;
	output_diff = (float) smooth_offset;
	output_integral = (float) offset_integral;
	output_offset = (float) offset;

	// Clamp a bit.
	if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit;
	if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit;

	// Now Calculate how many samples we need.
	rlen = ceil( ((double)nframes) * current_resample_factor )+2;
	assert( rlen > 2 );

	// Calculate resample_mean so we can init ourselves to saner values.
	resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor;
	/*
	 * now this should do it...
	 */

	outbuf = alloca( rlen * formats[format].sample_size * num_channels );

	resampbuf = alloca( rlen * sizeof( float ) );
	/*
	 * render jack ports to the outbuf...
	 */

	int chn = 0;
	JSList *node = playback_ports;
	JSList *src_node = playback_srcs;
	SRC_DATA src;

	while ( node != NULL)
	{
		jack_port_t *port = (jack_port_t *) node->data;
		float *buf = jack_port_get_buffer (port, nframes);

		SRC_STATE *src_state = src_node->data;

		src.data_in = buf;
		src.input_frames = nframes;

		src.data_out = resampbuf;
		src.output_frames = rlen;
		src.end_of_input = 0;

		src.src_ratio = current_resample_factor;

		src_process( src_state, &src );

		formats[format].jack_to_soundcard( outbuf + format[formats].sample_size * chn, resampbuf, src.output_frames_gen, num_channels*format[formats].sample_size, NULL);

		src_node = jack_slist_next (src_node);
		node = jack_slist_next (node);
		chn++;
	}

	// now write the output...
again:
	err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen);
	//err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen);
	if( err < 0 ) {
		printf( "err = %d\n", err );
		if (xrun_recovery(alsa_handle, err) < 0) {
			printf("Write error: %s\n", snd_strerror(err));
			exit(EXIT_FAILURE);
		}
		goto again;
	}

	return 0;
}

/**
 * the latency callback.
 * sets up the latencies on the ports.
 */

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
	jack_latency_range_t range;
	JSList *node;

	range.min = range.max = round(target_delay / static_resample_factor);

	if (mode == JackCaptureLatency) {
		for (node = capture_ports; node; node = jack_slist_next (node)) {
			jack_port_t *port = node->data;
			jack_port_set_latency_range (port, mode, &range);
		}
	} else {
		for (node = playback_ports; node; node = jack_slist_next (node)) {
			jack_port_t *port = node->data;
			jack_port_set_latency_range (port, mode, &range);
		}
	}
}


/**
 * Allocate the necessary jack ports...
 */

void alloc_ports( int n_capture, int n_playback ) {

	int port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
	int chn;
	jack_port_t *port;
	char buf[32];

	capture_ports = NULL;
	for (chn = 0; chn < n_capture; chn++)
	{
		snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1);

		port = jack_port_register (client, buf,
			JACK_DEFAULT_AUDIO_TYPE,
			port_flags, 0);

		if (!port)
		{
			printf( "jacknet_client: cannot register port for %s", buf);
			break;
		}

		capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) );
		capture_ports = jack_slist_append (capture_ports, port);
	}

	port_flags = JackPortIsInput;

	playback_ports = NULL;
	for (chn = 0; chn < n_playback; chn++)
	{
		snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1);

		port = jack_port_register (client, buf,
			JACK_DEFAULT_AUDIO_TYPE,
			port_flags, 0);

		if (!port)
		{
			printf( "jacknet_client: cannot register port for %s", buf);
			break;
		}

		playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) );
		playback_ports = jack_slist_append (playback_ports, port);
	}
}

/**
 * This is the shutdown callback for this JACK application.
 * It is called by JACK if the server ever shuts down or
 * decides to disconnect the client.
 */

void jack_shutdown (void *arg) {

	exit (1);
}

/**
 * be user friendly.
 * be user friendly.
 * be user friendly.
 */

void printUsage() {
fprintf(stderr, "usage: alsa_out [options]\n"
		"\n"
		"  -j <jack name> - client name\n"
		"  -S <server name> - server to connect\n"
		"  -d <alsa_device> \n"
		"  -c <channels> \n"
		"  -p <period_size> \n"
		"  -n <num_period> \n"
		"  -r <sample_rate> \n"
		"  -q <sample_rate quality [0..4]\n"
		"  -m <max_diff> \n"
		"  -t <target_delay> \n"
		"  -i  turns on instrumentation\n"
		"  -v  turns on printouts\n"
		"\n");
}


/**
 * the main function....
 */

void
sigterm_handler( int signal )
{
	quit = 1;
}


int main (int argc, char *argv[]) {
	char jack_name[30] = "alsa_out";
	int jack_opts = 0;
	char *server_name = NULL;

	extern char *optarg;
	extern int optind, optopt;
	int errflg=0;
	int c;

	while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:S:")) != -1) {
		switch(c) {
		case 'j':
			strcpy(jack_name,optarg);
			break;
		case 'r':
			sample_rate = atoi(optarg);
			break;
		case 'c':
			num_channels = atoi(optarg);
			break;
		case 'p':
			period_size = atoi(optarg);
			break;
		case 'n':
			num_periods = atoi(optarg);
			break;
		case 'd':
			alsa_device = strdup (optarg);
			break;
		case 't':
			target_delay = atoi(optarg);
			break;
		case 'q':
			samplerate_quality = atoi(optarg);
			break;
		case 'm':
			max_diff = atoi(optarg);
			break;
		case 'f':
			catch_factor = atoi(optarg);
			break;
		case 'F':
			catch_factor2 = atoi(optarg);
			break;
		case 'C':
			pclamp = (double) atoi(optarg);
			break;
		case 'Q':
			controlquant = (double) atoi(optarg);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'i':
			instrument = 1;
			break;
		case 's':
			smooth_size = atoi(optarg);
			break;
		case 'S':
			server_name = optarg;
			jack_opts |= JackServerName;
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n", optopt);
			errflg++;
			break;
		case '?':
			fprintf(stderr,
				"Unrecognized option: -%c\n", optopt);
			errflg++;
		}
	}
	if (errflg) {
		printUsage();
		exit(2);
	}

	if( (samplerate_quality < 0) || (samplerate_quality > 4) ) {
		fprintf (stderr, "invalid samplerate quality\n");
		return 1;
	}
	if ((client = jack_client_open (jack_name, jack_opts, NULL, server_name)) == 0) {
		fprintf (stderr, "jack server not running?\n");
		return 1;
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	   */

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `freewheel()' whenever
	   freewheel mode changes.
	   */

	jack_set_freewheel_callback (client, freewheel, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	   */

	jack_on_shutdown (client, jack_shutdown, 0);

	if (jack_set_latency_callback)
		jack_set_latency_callback (client, latency_cb, 0);

	// get jack sample_rate

	jack_sample_rate = jack_get_sample_rate( client );

	if( !sample_rate )
		sample_rate = jack_sample_rate;

	static_resample_factor =  (double) sample_rate / (double) jack_sample_rate;
	resample_lower_limit = static_resample_factor * 0.25;
	resample_upper_limit = static_resample_factor * 4.0;
	resample_mean = static_resample_factor;

	offset_array = malloc( sizeof(double) * smooth_size );
	if( offset_array == NULL ) {
		fprintf( stderr, "no memory for offset_array !!!\n" );
		exit(20);
	}
	window_array = malloc( sizeof(double) * smooth_size );
	if( window_array == NULL ) {
		fprintf( stderr, "no memory for window_array !!!\n" );
		exit(20);
	}
	int i;
	for( i=0; i<smooth_size; i++ ) {
		offset_array[i] = 0.0;
		window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) );
	}

	jack_buffer_size = jack_get_buffer_size( client );
	// Setup target delay and max_diff for the normal user, who does not play with them...
	if( !target_delay ) 
		target_delay = (num_periods*period_size / 2) - jack_buffer_size/2;

	if( !max_diff )
		max_diff = target_delay;

	if( max_diff > target_delay ) {
		fprintf( stderr, "target_delay (%d) can not be smaller than max_diff(%d)\n", target_delay, max_diff );
		exit(20);
	}
	if( (target_delay+max_diff) > (num_periods*period_size) ) {
		fprintf( stderr, "target_delay+max_diff (%d) can not be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size );
		exit(20);
	}
	// now open the alsa fd...
	alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods);
	if( alsa_handle == 0 )
		exit(20);

	printf( "selected sample format: %s\n", formats[format].name );

	// alloc input ports, which are blasted out to alsa...
	alloc_ports( 0, num_channels );

	outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels );
	resampbuf = malloc( num_periods * period_size * sizeof( float ) );
	tmpbuf = malloc( 512 * formats[format].sample_size * num_channels );

	if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL))
	{
		fprintf( stderr, "no memory for buffers.\n" );
		exit(20);
	}


	/* tell the JACK server that we are ready to roll */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	signal( SIGTERM, sigterm_handler );
	signal( SIGINT, sigterm_handler );

	if( verbose ) {
		while(!quit) {
			usleep(500000);
			if( output_new_delay ) {
				printf( "delay = %d\n", output_new_delay );
				output_new_delay = 0;
			}
			printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset );
		}
	} else if( instrument ) {
		printf( "# n\tresamp\tdiff\toffseti\tintegral\n");
		int n=0;
		while(!quit) {
			usleep(1000);
			printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral );
		}
	} else {
		while(!quit)
		{
			usleep(500000);
			if( output_new_delay ) {
				printf( "delay = %d\n", output_new_delay );
				output_new_delay = 0;
			}
		}
	}

	jack_deactivate( client );
	jack_client_close (client);
	exit (0);
}
07070100000048000081A400000000000000000000000161E2F7EE00000B44000000000000000000000000000000000000002500000000jack-example-tools-1/tools/bufsize.c/*
 *  bufsize.c -- change JACK buffer size.
 *
 *  Copyright (C) 2003 Jack O'Quin.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include <jack/transport.h>

char *package;				/* program name */
jack_client_t *client;
jack_nframes_t nframes;
int just_print_bufsize=0;

void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

void parse_arguments(int argc, char *argv[])
{
	/* basename $0 */
	package = strrchr(argv[0], '/');
	if (package == 0)
		package = argv[0];
	else
		package++;

	if (argc==1) {
		just_print_bufsize = 1;
		return;
	}
	if (argc < 2) {
		fprintf(stderr, "usage: %s <bufsize>\n", package);
		exit(9);
	}

	if (strspn (argv[1], "0123456789") != strlen (argv[1])) {
		fprintf(stderr, "usage: %s <bufsize>\n", package);
		exit(8);
	}

	nframes = strtoul(argv[1], NULL, 0);
	if (errno == ERANGE) {
		fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n",
			package, argv[1]);
		exit(2);
	}
	if (nframes < 1 || nframes > 16384) {
		fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n",
			package, argv[1]);
		exit(3);
	}
}

void silent_function( const char *ignore )
{
}

int main(int argc, char *argv[])
{
	int rc;
	parse_arguments(argc, argv);

	if (just_print_bufsize)
		jack_set_info_function( silent_function );

	/* become a JACK client */
	if ((client = jack_client_open(package, JackNoStartServer, NULL)) == 0) {
		fprintf(stderr, "JACK server not running?\n");
		exit(1);
	}

#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	if (just_print_bufsize) {
		fprintf(stdout, "%d\n", jack_get_buffer_size( client ) );
		rc = 0;
	}
	else
	{
		rc = jack_set_buffer_size(client, nframes);
		if (rc)
			fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc));
	}
	jack_client_close(client);

	return rc;
}
07070100000049000081A400000000000000000000000161E2F7EE000017F6000000000000000000000000000000000000002500000000jack-example-tools-1/tools/connect.c/*
    Copyright (C) 2002 Jeremy Hall

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <getopt.h>

#include <jack/jack.h>
#include <jack/session.h>

#define TRUE 1
#define FALSE 0

volatile int done = 0;

void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
{
	done = 1;
}

void
show_version (char *my_name)
{
	fprintf (stderr, "%s: JACK example tools version %s\n", my_name, __PROJECT_VERSION__);
}

void
show_usage (char *my_name)
{
	show_version (my_name);
	fprintf (stderr, "\nusage: %s [options] port1 port2\n", my_name);
	fprintf (stderr, "Connects two JACK ports together.\n\n");
	fprintf (stderr, "        -s, --server <name>   Connect to the jack server named <name>\n");
	fprintf (stderr, "        -v, --version         Output version information and exit\n");
	fprintf (stderr, "        -h, --help            Display this help message\n\n");
	fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

int
main (int argc, char *argv[])
{
	jack_client_t *client;
	jack_status_t status;
	char *server_name = NULL;
	int c;
	int option_index;
	jack_options_t options = JackNoStartServer;
	char *my_name = strrchr(argv[0], '/');
	jack_port_t *src_port = 0;
	jack_port_t *dst_port = 0;
	jack_port_t *port1 = 0;
	jack_port_t *port2 = 0;
	char portA[300];
	char portB[300];
	int use_uuid=0;
	int connecting, disconnecting;
	int port1_flags, port2_flags;
	int rc = 1;

	struct option long_options[] = {
		{ "server", 1, 0, 's' },
		{ "help", 0, 0, 'h' },
		{ "version", 0, 0, 'v' },
		{ "uuid", 0, 0, 'u' },
		{ 0, 0, 0, 0 }
	};

	while ((c = getopt_long (argc, argv, "s:hvu", long_options, &option_index)) >= 0) {
		switch (c) {
		case 's':
			server_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1));
			strcpy (server_name, optarg);
			options |= JackServerName;
			break;
		case 'u':
			use_uuid = 1;
			break;
		case 'h':
			show_usage (my_name);
			return 1;
			break;
		case 'v':
			show_version (my_name);
			return 1;
			break;
		default:
			show_usage (my_name);
			return 1;
			break;
		}
	}

	connecting = disconnecting = FALSE;
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	if (strstr(my_name, "disconnect")) {
		disconnecting = 1;
	} else if (strstr(my_name, "connect")) {
		connecting = 1;
	} else {
		fprintf(stderr, "ERROR! client should be called jack_connect or jack_disconnect. client is called %s\n", my_name);
		return 1;
	}

	if (argc < 3) {
		show_usage(my_name);
		return 1;
	}

	/* try to become a client of the JACK server */

	if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) {
		fprintf (stderr, "jack server not running?\n");
		return 1;
	}

	jack_set_port_connect_callback(client, port_connect_callback, NULL);

	/* find the two ports */

	if( use_uuid ) {
		char *tmpname;
		char *clientname;
		char *portname;
		tmpname = strdup( argv[argc-1] );
		portname = strchr( tmpname, ':' );
		portname[0] = '\0';
		portname+=1;
		clientname = jack_get_client_name_by_uuid( client, tmpname );
		if( clientname ) {

			snprintf( portA, sizeof(portA), "%s:%s", clientname, portname );
			jack_free( clientname );
		} else {
			snprintf( portA, sizeof(portA), "%s", argv[argc-1] );
		}
		free( tmpname );

		tmpname = strdup( argv[argc-2] );
		portname = strchr( tmpname, ':' );
		portname[0] = '\0';
		portname+=1;
		clientname = jack_get_client_name_by_uuid( client, tmpname );
		if( clientname ) {
			snprintf( portB, sizeof(portB), "%s:%s", clientname, portname );
			jack_free( clientname );
		} else {
			snprintf( portB, sizeof(portB), "%s", argv[argc-2] );
		}

		free( tmpname );

	} else {
		snprintf( portA, sizeof(portA), "%s", argv[argc-1] );
		snprintf( portB, sizeof(portB), "%s", argv[argc-2] );
	}
	if ((port1 = jack_port_by_name(client, portA)) == 0) {
		fprintf (stderr, "ERROR %s not a valid port\n", portA);
		goto exit;
	}
	if ((port2 = jack_port_by_name(client, portB)) == 0) {
		fprintf (stderr, "ERROR %s not a valid port\n", portB);
		goto exit;
	}

	port1_flags = jack_port_flags (port1);
	port2_flags = jack_port_flags (port2);

	if (port1_flags & JackPortIsInput) {
		if (port2_flags & JackPortIsOutput) {
			src_port = port2;
			dst_port = port1;
		}
	} else {
		if (port2_flags & JackPortIsInput) {
			src_port = port1;
			dst_port = port2;
		}
	}

	if (!src_port || !dst_port) {
		fprintf (stderr, "arguments must include 1 input port and 1 output port\n");
		goto exit;
	}

	/* tell the JACK server that we are ready to roll */
	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		goto exit;
	}

	/* connect the ports. Note: you can't do this before
	   the client is activated (this may change in the future).
	*/

	if (connecting) {
		if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
			fprintf (stderr, "cannot connect client, already connected?\n");
			goto exit;
		}
	}
	if (disconnecting) {
		if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
			fprintf (stderr, "cannot disconnect client, already disconnected?\n");
			goto exit;
		}
	}

	// Wait for connection/disconnection to be effective
	while(!done) {
#ifdef WIN32
		Sleep(10);
#else
		usleep(10000);
#endif
	}

	/* everything was ok, so setting exitcode to 0 */
	rc = 0;

exit:
	jack_client_close (client);
	exit (rc);
}
0707010000004A000081A400000000000000000000000161E2F7EE00001003000000000000000000000000000000000000002300000000jack-example-tools-1/tools/evmon.c/*
    Copyright (C) 2007 Paul Davis

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <string.h>
#include <signal.h>
#include <stdlib.h>

#include <jack/jack.h>
#include <jack/metadata.h>
#include <jack/uuid.h>

jack_client_t *client;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void
port_rename_callback (jack_port_id_t port, const char* old_name, const char* new_name, void* arg)
{
	printf ("Port %d renamed from %s to %s\n", port, old_name, new_name);
}

static void
port_callback (jack_port_id_t port, int yn, void* arg)
{
	printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered"));
}

static void
connect_callback (jack_port_id_t a, jack_port_id_t b, int yn, void* arg)
{
	printf ("Ports %d and %d %s\n", a, b, (yn ? "connected" : "disconnected"));
}

static void
client_callback (const char* client, int yn, void* arg)
{
	printf ("Client %s %s\n", client, (yn ? "registered" : "unregistered"));
}

static int
graph_callback (void* arg)
{
	printf ("Graph reordered\n");
	return 0;
}

static void
propchange (jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg)
{
	char buf[JACK_UUID_STRING_SIZE];
	const char* action = "";

	switch (change) {
	case PropertyCreated:
		action = "created";
		break;

	case PropertyChanged:
		action = "changed";
		break;

	case PropertyDeleted:
		action = "deleted";
		break;
	}

	if (jack_uuid_empty (subject)) {
		printf ("All properties changed!\n");
	} else {
		jack_uuid_unparse (subject, buf);

		if (key) {
			printf ("key [%s] for %s %s\n", key, buf, action);
		} else {
			printf ("all keys for %s %s\n", buf, action);
		}
	}
}

int
main (int argc, char *argv[])
{
	jack_options_t options = JackNullOption;
	jack_status_t status;

	if ((client = jack_client_open ("event-monitor", options, &status, NULL)) == 0) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		return 1;
	}
	
	if (jack_set_port_registration_callback (client, port_callback, NULL)) {
		fprintf (stderr, "cannot set port registration callback\n");
		return 1;
	}
	if (jack_set_port_rename_callback (client, port_rename_callback, NULL)) {
		fprintf (stderr, "cannot set port registration callback\n");
		return 1;
	}
	if (jack_set_port_connect_callback (client, connect_callback, NULL)) {
		fprintf (stderr, "cannot set port connect callback\n");
		return 1;
	}
	if (jack_set_client_registration_callback (client, client_callback, NULL)) {
		fprintf (stderr, "cannot set client registration callback\n");
		return 1;
	}
	if (jack_set_graph_order_callback (client, graph_callback, NULL)) {
		fprintf (stderr, "cannot set graph order registration callback\n");
		return 1;
	}
	if (jack_set_property_change_callback (client, propchange, NULL)) {
		fprintf (stderr, "cannot set property change callback\n");
		return 1;
	}
	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		return 1;
	}

#ifndef WIN32
	signal(SIGINT, signal_handler);
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGABRT, signal_handler);
	signal(SIGTERM, signal_handler);

#ifdef WIN32
	Sleep(INFINITE);
#else
	sleep (-1);
#endif
	exit (0);
}

0707010000004B000081A400000000000000000000000161E2F7EE0000085A000000000000000000000000000000000000002700000000jack-example-tools-1/tools/freewheel.c/*
 *  freewheel - start/stop JACK "freewheeling" mode
 *
 *  Copyright (C) 2003 Paul Davis.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include <jack/transport.h>

char *package;				/* program name */
jack_client_t *client;
int onoff;

static void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

static void parse_arguments(int argc, char *argv[])
{
	if (argc < 2) {
		fprintf(stderr, "usage: %s y|n\n", package);
		exit(9);
	}

	if (argv[1][0] == 'y' || argv[1][0] == 'Y' || argv[1][0] == '1') {
		onoff = 1;
	} else {
		onoff = 0;
	}
}

int
main (int argc, char *argv[])
{
	parse_arguments (argc, argv);

	/* become a JACK client */
	if ((client = jack_client_open ("freewheel", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		exit(1);
	}

#ifndef WIN32
	signal (SIGQUIT, signal_handler);
	signal (SIGHUP, signal_handler);
#endif
	signal (SIGTERM, signal_handler);
	signal (SIGINT, signal_handler);

	jack_on_shutdown (client, jack_shutdown, 0);

	if (jack_set_freewheel (client, onoff)) {
		fprintf (stderr, "failed to reset freewheel mode\n");
	}

	jack_client_close(client);
	return 0;
}
0707010000004C000081A400000000000000000000000161E2F7EE00001C76000000000000000000000000000000000000002700000000jack-example-tools-1/tools/iodelay.cpp/*
    Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

// --------------------------------------------------------------------------------

#include <stdlib.h>
#include <stdio.h>
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <math.h>
#include <unistd.h>
#include <jack/jack.h>

struct Freq
{
    int   p;
    int   f;
    float xa;
    float ya;
    float x1;
    float y1;
    float x2;
    float y2;
};


struct MTDM
{
    double  _del;
    double  _err;
    float   _wlp;
    int     _cnt;
    int     _inv;

    struct Freq _freq [13];
};


struct MTDM * mtdm_new (double fsamp)
{
    int   i;
    struct Freq  *F;

    struct MTDM *retval = (MTDM *)malloc( sizeof(struct MTDM) );

    if (retval==NULL)
	    return NULL;

    retval->_cnt = 0;
    retval->_inv = 0;

    retval->_freq [0].f  = 4096;
    retval->_freq [1].f  = 2048;
    retval->_freq [2].f  = 3072;
    retval->_freq [3].f  = 2560;
    retval->_freq [4].f  = 2304;
    retval->_freq [5].f  = 2176; 
    retval->_freq [6].f  = 1088;
    retval->_freq [7].f  = 1312;
    retval->_freq [8].f  = 1552;
    retval->_freq [9].f  = 1800;
    retval->_freq [10].f = 3332;
    retval->_freq [11].f = 3586;
    retval->_freq [12].f = 3841;
    retval->_wlp = 200.0f / fsamp;
    for (i = 0, F = retval->_freq; i < 13; i++, F++) {
        F->p = 128;
        F->xa = F->ya = 0.0f;
        F->x1 = F->y1 = 0.0f;
        F->x2 = F->y2 = 0.0f;
    }

    return retval;
}

int mtdm_process (struct MTDM *self, size_t len, float *ip, float *op)
{
    int    i;
    float  vip, vop, a, c, s;
    struct Freq   *F;

    while (len--)
    {
        vop = 0.0f;
        vip = *ip++;
        for (i = 0, F = self->_freq; i < 13; i++, F++)
        {
            a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; 
            F->p += F->f;
            c =  cosf (a); 
            s = -sinf (a); 
            vop += (i ? 0.01f : 0.20f) * s;
            F->xa += s * vip;
            F->ya += c * vip;
        } 
        *op++ = vop;
        if (++self->_cnt == 16)
        {
            for (i = 0, F = self->_freq; i < 13; i++, F++)
            {
                F->x1 += self->_wlp * (F->xa - F->x1 + 1e-20);
                F->y1 += self->_wlp * (F->ya - F->y1 + 1e-20);
                F->x2 += self->_wlp * (F->x1 - F->x2 + 1e-20);
                F->y2 += self->_wlp * (F->y1 - F->y2 + 1e-20);
                F->xa = F->ya = 0.0f;
            }
            self->_cnt = 0;
        }
    }

    return 0;
}

int mtdm_resolve (struct MTDM *self)
{
    int     i, k, m;
    double  d, e, f0, p;
    struct Freq *F = self->_freq;

    if (hypot (F->x2, F->y2) < 0.001) return -1;
    d = atan2 (F->y2, F->x2) / (2 * M_PI);
    if (self->_inv) d += 0.5;
    if (d > 0.5) d -= 1.0;
    f0 = self->_freq [0].f;
    m = 1;
    self->_err = 0.0;
    for (i = 0; i < 12; i++)
    {
        F++;
        p = atan2 (F->y2, F->x2) / (2 * M_PI) - d * F->f / f0;
        if (self->_inv) p += 0.5;
        p -= floor (p);
        p *= 2;
        k = (int)(floor (p + 0.5));
        e = fabs (p - k);
        if (e > self->_err) self->_err = e;
        if (e > 0.4) return 1; 
        d += m * (k & 1);
        m *= 2;
    }  
    self->_del = 16 * d;

    return 0;
}

void mtdm_invert (struct MTDM *self)
{
	self->_inv ^= 1;
}
// --------------------------------------------------------------------------------

static struct MTDM    *mtdm;
static jack_client_t  *jack_handle;
static jack_port_t    *jack_capt;
static jack_port_t    *jack_play;

jack_latency_range_t   capture_latency = {UINT32_MAX, UINT32_MAX};
jack_latency_range_t   playback_latency = {UINT32_MAX, UINT32_MAX};

void
latency_cb (jack_latency_callback_mode_t mode, void *arg)
{
	jack_latency_range_t range;

	range.min = range.max = 0;

	if (mode == JackCaptureLatency) {
		jack_port_set_latency_range (jack_play, mode, &range);
		jack_port_get_latency_range (jack_capt, mode, &range);
		if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) {
			capture_latency = range;
			printf ("new capture latency: [%d, %d]\n", range.min, range.max);
		}
	} else {
		jack_port_set_latency_range (jack_capt, mode, &range);
		jack_port_get_latency_range (jack_play, mode, &range);
		if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) {
			playback_latency = range;
			printf ("new playback latency: [%d, %d]\n", range.min, range.max);
		}
	}

}

int jack_callback (jack_nframes_t nframes, void *arg)
{
    float *ip, *op;

    ip = (float *)(jack_port_get_buffer (jack_capt, nframes));
    op = (float *)(jack_port_get_buffer (jack_play, nframes));
    mtdm_process (mtdm, nframes, ip, op);
    return 0;
}

int main (int ac, char *av [])
{
    float          t;
    jack_status_t  s;

    jack_handle = jack_client_open ("jack_delay", JackNoStartServer, &s);
    if (jack_handle == 0)
    {
        fprintf (stderr, "Can't connect to Jack, is the server running ?\n");
        exit (1);
    }

    mtdm = mtdm_new(jack_get_sample_rate(jack_handle));

    jack_set_process_callback (jack_handle, jack_callback, 0);

    if (jack_set_latency_callback)
	    jack_set_latency_callback (jack_handle, latency_cb, 0);

    jack_capt = jack_port_register (jack_handle, "in",  JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
    jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

    t = 1000.0f / jack_get_sample_rate (jack_handle);

    if (jack_activate (jack_handle))
    {
        fprintf(stderr, "Can't activate Jack");
        return 1;
    }

    while (1)
    {
 
    #ifdef WIN32 
        Sleep (250); 
    #else 
        usleep (250000); 
 	#endif        
        if (mtdm_resolve (mtdm) < 0) printf ("Signal below threshold...\n");
        else 
        {
            jack_nframes_t systemic_latency;

            if (mtdm->_err > 0.3) 
            {
                mtdm_invert ( mtdm );
                mtdm_resolve ( mtdm );
            }
            systemic_latency = (jack_nframes_t) floor (mtdm->_del - (capture_latency.max + playback_latency.max));

            printf ("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O", mtdm->_del, mtdm->_del * t, 
                    systemic_latency, systemic_latency/2);
            if (mtdm->_err > 0.2) printf (" ??");
                if (mtdm->_inv) printf (" Inv");
            printf ("\n");
        }
    }

    return 0;
}

// --------------------------------------------------------------------------------
0707010000004D000081A400000000000000000000000161E2F7EE000016A5000000000000000000000000000000000000002400000000jack-example-tools-1/tools/ipload.c/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <getopt.h>
#include <jack/jack.h>
#include <jack/intclient.h>

jack_client_t *client;
jack_intclient_t intclient;
char *client_name;
char *intclient_name;
char *load_name;
char *load_init = "";
char *server_name = NULL;
int autoclose_opt = 0;
int wait_opt = 0;
volatile int idling = 1;

static void
signal_handler (int sig)
{
	/* do nothing if internal client closed itself */
	if (idling == 0)
		return;

	jack_status_t status;

	fprintf (stderr, "signal received, unloading...");
	status = jack_internal_client_unload (client, intclient);
	if (status & JackFailure)
		fprintf (stderr, "(failed), status = 0x%2.0x\n", status);
	else
		fprintf (stderr, "(succeeded)\n");
	if (autoclose_opt)
		jack_deactivate(client);
	jack_client_close (client);
	exit (0);
}

static void
registration_callback (const char *name, int reg, void *arg)
{
	if (reg || strcmp(intclient_name, name))
		return;

	/* this will stop the wait loop and thus close this application. */
	idling = 0;
	return;

	/* unused */
	(void)arg;
}

static void
show_usage ()
{
	fprintf (stderr, "usage: %s [ options ] client-name [ load-name "
		 "[ init-string]]\n\noptions:\n", client_name);
	fprintf (stderr,
		 "\t-h, --help \t\t print help message\n"
		 "\t-a, --autoclose\t automatically close when intclient is unloaded\n"
		 "\t-i, --init string\t initialize string\n"
		 "\t-s, --server name\t select JACK server\n"
		 "\t-w, --wait \t\t wait for signal, then unload\n"
		 "\n"
		);
}

static int
parse_args (int argc, char *argv[])
{
	int c;
	int option_index = 0;
	char *short_options = "hai:s:w";
	struct option long_options[] = {
		{ "help", 0, 0, 'h' },
		{ "autoclose", 0, 0, 'a' },
		{ "init", required_argument, 0, 'i' },
		{ "server", required_argument, 0, 's' },
		{ "wait", 0, 0, 'w' },
		{ 0, 0, 0, 0 }
	};

	client_name = strrchr(argv[0], '/');
	if (client_name == NULL) {
		client_name = argv[0];
	} else {
		client_name++;
	}

	while ((c = getopt_long (argc, argv, short_options, long_options,
				 &option_index)) >= 0) {
		switch (c) {
		case 'a':
			autoclose_opt = 1;
			break;
		case 'i':
			load_init = optarg;
			break;
		case 's':
			server_name = optarg;
			break;
		case 'w':
			wait_opt = 1;
			break;
		case 'h':
		default:
			show_usage ();
			return 1;
		}
	}

	/* autoclose makes no sense without wait */
	if (autoclose_opt && ! wait_opt)
		autoclose_opt = 0;

	if (optind == argc) {		/* no positional args? */
		show_usage ();
		return 1;
	}
	if (optind < argc)
		load_name = intclient_name = argv[optind++];

	if (optind < argc)
		load_name = argv[optind++];

	if (optind < argc)
		load_init = argv[optind++];

	//fprintf (stderr, "client-name = `%s', load-name = `%s', "
	//	 "load-init = `%s', wait = %d\n",
	//	 intclient_name, load_name, load_init, wait_opt);

	return 0;			/* args OK */
}

int
main (int argc, char *argv[])
{
	jack_status_t status;
	char* name;

	/* parse and validate command arguments */
	if (parse_args (argc, argv))
		exit (1);		/* invalid command line */

	/* first, become a JACK client */
	client = jack_client_open (client_name, JackServerName,
				   &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* then, load the internal client */
	intclient = jack_internal_client_load (client, intclient_name,
					       (JackLoadName|JackLoadInit),
					       &status, load_name, load_init);
	if (status & JackFailure) {
		fprintf (stderr, "could not load %s, intclient = %d status = 0x%2.0x\n",
			 load_name, (int)intclient, status);
		return 2;
	}
	if (status & JackNameNotUnique) {
		intclient_name =
			jack_get_internal_client_name (client, intclient);
		fprintf (stderr, "unique internal client name `%s' assigned\n",
			 intclient_name);
	}

	fprintf (stdout, "%s is running.\n", load_name);

	name = jack_get_internal_client_name(client, intclient);
	if (name) {
		printf("client name = %s\n", name);
		free(name);
	}
	fflush(stdout);

	if (autoclose_opt) {
		jack_set_client_registration_callback(client, registration_callback, NULL);
		jack_activate(client);
	}

	if (wait_opt) {
		/* define a signal handler to unload the client, then
		 * wait for it to exit */
	#ifdef WIN32
		signal(SIGINT, signal_handler);
		signal(SIGABRT, signal_handler);
		signal(SIGTERM, signal_handler);
	#else
		signal(SIGQUIT, signal_handler);
		signal(SIGTERM, signal_handler);
		signal(SIGHUP, signal_handler);
		signal(SIGINT, signal_handler);
	#endif

		while (idling) {
			#ifdef WIN32
				Sleep(1000);
			#else
				sleep (1);
			#endif
		}
	}

	if (autoclose_opt) {
		jack_deactivate(client);
	}

	jack_client_close(client);
	return 0;
}

0707010000004E000081A400000000000000000000000161E2F7EE00000B25000000000000000000000000000000000000002600000000jack-example-tools-1/tools/ipunload.c/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#if !defined(__JACK1__) && !defined(__JACK2__)
# error neither __JACK1__ or __JACK2__ is defined, this cannot happen
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <jack/jack.h>
#include <jack/intclient.h>

int
main (int argc, char *argv[])
{
	char *my_name;
	char *client_name;
	jack_client_t *client;
	jack_status_t status;
	jack_intclient_t intclient;

	/* validate args */
	if ((argc < 2) || (argc > 3)) {
		fprintf (stderr, "usage: %s client-name [ server-name ]]\n",
			 argv[0]);
		return 1;
	}

	/* use `basename $0` for my own client name */
	my_name = strrchr(argv[0], '/');
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name++;
	}

	/* first, become a JACK client */
	if (argc > 2) {
		client = jack_client_open (my_name,
					   (JackServerName|JackNoStartServer),
					   &status, argv[2]);
	} else {
		client = jack_client_open (my_name, JackNoStartServer, &status);
	}

	if (client == NULL) {
		if (status & JackServerFailed) {
			fprintf (stderr, "JACK server not running.\n");
		} else {
			fprintf (stderr, "JACK open failed, "
				 "status = 0x%2.0x\n", status);
		}
		exit (1);
	}

	/* then, get the internal client handle */
	client_name = argv[1];
#ifdef __JACK1__
	if (jack_internal_client_handle (client, client_name, &status, &intclient) != 0) {
		if (status & JackFailure) {
			fprintf (stderr, "client %s not found.\n", client_name);
		}
		exit (2);
	}
#endif

#ifdef __JACK2__
	intclient = jack_internal_client_handle (client, client_name, &status);
	if (status & JackFailure) {
		fprintf (stderr, "client %s not found.\n", client_name);
		exit (2);
	}
#endif

	/* now, unload the internal client */
	status = jack_internal_client_unload (client, intclient);
	if (status & JackFailure) {
		if (status & JackInvalidOption) {
			fprintf (stderr, "I'm sorry Dave, I can't do that\n");
		} else if (status & JackNoSuchClient) {
			fprintf (stderr, "client %s is gone.\n", client_name);
		} else {
			fprintf (stderr, "could not unload %s, "
				 "returns 0x%2.0x\n", client_name, status);
		}
		exit (3);
	} else {
		fprintf (stdout, "%s unloaded.\n", client_name);
	}

	jack_client_close(client);
	return 0;
}
0707010000004F000081A400000000000000000000000161E2F7EE0000094A000000000000000000000000000000000000002700000000jack-example-tools-1/tools/load_test.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>

#include <time.h>

#include <jack/jack.h>

char * my_name;
jack_client_t *client;
unsigned int wait_timeout = 1000;

void
show_version (void)
{
	fprintf (stderr, "%s: JACK example tools version %s\n", my_name, __PROJECT_VERSION__);
}

void
show_usage (void)
{
	show_version ();
	fprintf (stderr, "\nUsage: %s [options]\n", my_name);
	fprintf (stderr, "this is a test client, which just sleeps in its process_cb to simulate cpu load\n");
	fprintf (stderr, "options:\n");
	fprintf (stderr, "        -t, --timeout         Wait timeout in seconds\n");
	fprintf (stderr, "        -h, --help            Display this help message\n");
	fprintf (stderr, "        --version             Output version information and exit\n\n");
	fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

int
process_cb (jack_nframes_t nframes, void *arg)
{
	jack_time_t now  = jack_get_time();
	jack_time_t wait = now + wait_timeout; 

	while (jack_get_time() < wait) ;

	return 0;      
}

int
main (int argc, char *argv[])
{
	int c;
	int option_index;
	
	struct option long_options[] = {
		{ "timeout", 1, 0, 't' },
		{ "help", 0, 0, 'h' },
		{ "version", 0, 0, 'v' },
		{ 0, 0, 0, 0 }
	};

	my_name = strrchr(argv[0], '/');
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	while ((c = getopt_long (argc, argv, "t:hv", long_options, &option_index)) >= 0) {
		switch (c) {
		case 't':
			wait_timeout = atoi(optarg);
			break;
		case 'h':
			show_usage ();
			return 1;
			break;
		case 'v':
			show_version ();
			return 1;
			break;
		default:
			show_usage ();
			return 1;
			break;
		}
	}

	/* try to open server in a loop. breaking under certein conditions */

	client = jack_client_open( "load_test", JackNullOption, NULL );

	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	jack_set_process_callback( client, process_cb, NULL );

	jack_activate (client);

	sleep( -1 );

	exit (0);
}
07070100000050000081A400000000000000000000000161E2F7EE00001EB2000000000000000000000000000000000000002100000000jack-example-tools-1/tools/lsp.c/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <string.h>
#include <getopt.h>
#include <inttypes.h>

#include <jack/jack.h>
#include <jack/session.h>
#include <jack/uuid.h>

char * my_name;

static void
show_version (void)
{
	fprintf (stderr, "%s: JACK example tools version %s\n", my_name, __PROJECT_VERSION__);
}

static void
printf_name2uuid (jack_client_t* client, const char* pname)
{
	char *port_component = strchr( pname, ':' );
	size_t csize = port_component - pname + 1;
	char client_component[csize];
	snprintf(client_component, csize, "%s", pname);

	char *uuid = jack_get_uuid_for_client_name(client, client_component);
	if (uuid) {
		printf("%s%s\n", uuid, port_component );
	} else {
		printf("%s\n",pname);
	}
	jack_free(uuid);
}

static void
show_usage (void)
{
	show_version ();
	fprintf (stderr, "\nUsage: %s [options] [filter string]\n", my_name);
	fprintf (stderr, "List active Jack ports, and optionally display extra information.\n");
	fprintf (stderr, "Optionally filter ports which match ALL strings provided after any options.\n\n");
	fprintf (stderr, "Display options:\n");
	fprintf (stderr, "        -s, --server <name>   Connect to the jack server named <name>\n");
	fprintf (stderr, "        -A, --aliases         List aliases for each port\n");
	fprintf (stderr, "        -c, --connections     List connections to/from each port\n");
	fprintf (stderr, "        -l, --port-latency    Display per-port latency in frames at each port\n");
	fprintf (stderr, "        -L, --total-latency   Display total latency in frames at each port\n");
	fprintf (stderr, "        -p, --properties      Display port properties. Output may include:\n"
			 "                              input|output, can-monitor, physical, terminal\n\n");
	fprintf (stderr, "        -t, --type            Display port type\n");
	fprintf (stderr, "        -u, --uuid            Display uuid instead of client name (if available)\n");
	fprintf (stderr, "        -U, --port-uuid       Display port uuid\n");
	fprintf (stderr, "        -h, --help            Display this help message\n");
	fprintf (stderr, "        --version             Output version information and exit\n\n");
	fprintf (stderr, "For more information see http://jackaudio.org/\n");
}

int
main (int argc, char *argv[])
{
	jack_client_t *client;
	jack_status_t status;
	jack_options_t options = JackNoStartServer;
	const char **ports, **connections;
	unsigned int i, j, k;
	int skip_port;
	int show_aliases = 0;
	int show_con = 0;
	int show_port_latency = 0;
	int show_total_latency = 0;
	int show_properties = 0;
	int show_type = 0;
	int show_uuid = 0;
	int show_port_uuid = 0;
	int c;
	int option_index;
	char* aliases[2];
	char *server_name = NULL;

	struct option long_options[] = {
		{ "server", 1, 0, 's' },
		{ "aliases", 0, 0, 'A' },
		{ "connections", 0, 0, 'c' },
		{ "port-latency", 0, 0, 'l' },
		{ "total-latency", 0, 0, 'L' },
		{ "properties", 0, 0, 'p' },
		{ "type", 0, 0, 't' },
		{ "uuid", 0, 0, 'u' },
		{ "port-uuid", 0, 0, 'U' },
		{ "help", 0, 0, 'h' },
		{ "version", 0, 0, 'v' },
		{ 0, 0, 0, 0 }
	};

	my_name = strrchr(argv[0], '/');
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	while ((c = getopt_long (argc, argv, "s:AclLphvtuU", long_options, &option_index)) >= 0) {
		switch (c) {
		case 's':
			server_name = (char *) malloc (sizeof (char) * strlen(optarg));
			strcpy (server_name, optarg);
			options |= JackServerName;
			break;
		case 'A':
			aliases[0] = (char *) malloc (jack_port_name_size());
			aliases[1] = (char *) malloc (jack_port_name_size());
			show_aliases = 1;
			break;
		case 'c':
			show_con = 1;
			break;
		case 'l':
			show_port_latency = 1;
			break;
		case 'L':
			show_total_latency = 1;
			break;
		case 'p':
			show_properties = 1;
			break;
		case 't':
			show_type = 1;
			break;
		case 'u':
			show_uuid = 1;
			break;
		case 'U':
			show_port_uuid = 1;
			break;
		case 'h':
			show_usage ();
			return 1;
			break;
		case 'v':
			show_version ();
			return 1;
			break;
		default:
			show_usage ();
			return 1;
			break;
		}
	}

	/* Open a client connection to the JACK server.  Starting a
	 * new server only to list its ports seems pointless, so we
	 * specify JackNoStartServer. */
	if ((client = jack_client_open ("lsp", options, &status, server_name)) == 0) {
		fprintf (stderr, "Error: cannot connect to JACK, ");
		if (status & JackServerFailed) {
			fprintf (stderr, "server is not running.\n");
		} else {
			fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n", status);
		}
		return 1;
	}

	ports = jack_get_ports (client, NULL, NULL, 0);

	for (i = 0; ports && ports[i]; ++i) {
		// skip over any that don't match ALL of the strings presented at command line
		skip_port = 0;
		for (k = optind; k < argc; k++){
			if (strstr(ports[i], argv[k]) == NULL ){
				skip_port = 1;
			}
		}
		if (skip_port) continue;

		if (show_uuid) {
			printf_name2uuid(client, ports[i]);
		} else {
			printf ("%s\n", ports[i]);
		}

		jack_port_t *port = jack_port_by_name (client, ports[i]);

		if (show_port_uuid) {
			char buf[JACK_UUID_STRING_SIZE];
			jack_uuid_t uuid = jack_port_uuid (port);
			jack_uuid_unparse (uuid, buf);
			printf ("	uuid: %s\n", buf);
		}

		if (show_aliases) {
			int cnt;
			int i;

			cnt = jack_port_get_aliases (port, aliases);
			for (i = 0; i < cnt; ++i) {
				printf ("   %s\n", aliases[i]);
			}
		}

		if (show_con) {
			if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) {
				for (j = 0; connections[j]; j++) {
					printf("   ");
					if (show_uuid) {
						printf_name2uuid(client, connections[j]);
					} else {
						printf("%s\n", connections[j]);
					}
				}
				jack_free (connections);
			}
		}
		if (show_port_latency) {
			if (port) {
				jack_latency_range_t range;

				jack_port_get_latency_range (port, JackPlaybackLatency, &range);
				printf ("	port playback latency = [ %" PRIu32 " %" PRIu32 " ] frames\n",
					range.min, range.max);

				jack_port_get_latency_range (port, JackCaptureLatency, &range);
				printf ("	port capture latency = [ %" PRIu32 " %" PRIu32 " ] frames\n",
					range.min, range.max);
			}
		}
		if (show_total_latency) {
			if (port) {
				printf ("	total latency = %d frames\n",
					jack_port_get_total_latency (client, port));
			}
		}
		if (show_properties) {
			if (port) {
				int flags = jack_port_flags (port);
				printf ("	properties: ");
				if (flags & JackPortIsInput) {
					fputs ("input,", stdout);
				}
				if (flags & JackPortIsOutput) {
					fputs ("output,", stdout);
				}
				if (flags & JackPortCanMonitor) {
					fputs ("can-monitor,", stdout);
				}
				if (flags & JackPortIsPhysical) {
					fputs ("physical,", stdout);
				}
				if (flags & JackPortIsTerminal) {
					fputs ("terminal,", stdout);
				}
				putc ('\n', stdout);
			}
		}
		if (show_type) {
			if (port) {
				putc ('\t', stdout);
				fputs (jack_port_type (port), stdout);
				putc ('\n', stdout);
			}
		}
	}

	if (show_aliases) {
		free(aliases[0]);
		free(aliases[1]);
	}
	if (ports)
		jack_free (ports);
	jack_client_close (client);
	exit (0);
}
07070100000051000081A400000000000000000000000161E2F7EE0000104F000000000000000000000000000000000000002700000000jack-example-tools-1/tools/meson.buildexe_jack_alias = executable(
  'jack_alias',
  c_args: c_args_common,
  sources: ['alias.c'],
  dependencies: [dep_jack],
  install: true
)

if build_alsa_in_out
  exe_alsa_in = executable(
    'alsa_in',
    sources: ['alsa_in.c', '../common/memops.c'],
    include_directories: ['../common'],
    dependencies: [dep_alsa, dep_jack, dep_samplerate, lib_m],
    install: true
  )
  exe_alsa_out = executable(
    'alsa_out',
    sources: ['alsa_out.c', '../common/memops.c'],
    include_directories: ['../common'],
    dependencies: [dep_alsa, dep_jack, dep_samplerate, lib_m],
    install: true
  )
endif

exe_jack_bufsize = executable(
  'jack_bufsize',
  sources: ['bufsize.c'],
  dependencies: [dep_jack, dep_threads],
  install: true
)

exe_jack_connect = executable(
  'jack_connect',
  c_args: c_args_common,
  sources: ['connect.c'],
  dependencies: [dep_jack],
  install: true
)
if os != 'windows'
meson.add_install_script(
  '../scripts/meson_create_symlink',
  get_option('bindir'),
  'jack_connect',
  'jack_disconnect'
)
endif

exe_jack_evmon = executable(
  'jack_evmon',
  sources: ['evmon.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_freewheel = executable(
  'jack_freewheel',
  sources: ['freewheel.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_iodelay = executable(
  'jack_iodelay',
  sources: ['iodelay.cpp'],
  dependencies: [dep_jack, lib_m],
  install: true
)

exe_jack_load = executable(
  'jack_load',
  sources: ['ipload.c'],
  dependencies: [dep_jack],
  install: true
)

if has_jack1_internal_client and not has_jack2_internal_client
  c_args_jack_unload = c_args_common + ['-D__JACK1__']
endif
if not has_jack1_internal_client and has_jack2_internal_client
  c_args_jack_unload = c_args_common + ['-D__JACK2__']
endif
exe_jack_unload = executable(
  'jack_unload',
  c_args: c_args_jack_unload,
  sources: ['ipunload.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_unload = executable(
  'jack_load_test',
  c_args: c_args_common,
  sources: ['load_test.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_lsp = executable(
  'jack_lsp',
  c_args: c_args_common,
  sources: ['lsp.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_midi_dump = executable(
  'jack_midi_dump',
  sources: ['midi_dump.c'],
  dependencies: [dep_jack, dep_threads],
  install: true
)

exe_jack_monitor_client = executable(
  'jack_monitor_client',
  sources: ['monitor_client.c'],
  dependencies: [dep_jack],
  install: true
)


if build_jack_netsource
  c_args_netsource = c_args_common + ['-DNO_JACK_ERROR']
  deps_netsource = [dep_jack, dep_samplerate, lib_m]
  if opus_support
    c_args_netsource += ['-DHAVE_OPUS']
    deps_netsource += [dep_opus]
  endif
  if has_ppoll
    c_args_netsource += ['-DHAVE_PPOLL']
  endif

  exe_jack_netsource = executable(
    'jack_netsource',
    c_args: c_args_netsource,
    sources: ['netsource.c', '../common/netjack_packet.c'],
    include_directories: ['../common'],
    dependencies: deps_netsource,
    install: true
  )
endif

exe_jack_property = executable(
  'jack_property',
  sources: ['property.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_samplerate = executable(
  'jack_samplerate',
  sources: ['samplerate.c'],
  dependencies: [dep_jack],
  install: true
)

# dont install, jack session is deprecated
exe_jack_session_notify = executable(
  'jack_session_notify',
  sources: ['session_notify.c'],
  dependencies: [dep_jack],
  c_args: ['-Wno-deprecated-declarations'],
  install: false
)

jack_transport_c_args = c_args_common
jack_transport_deps = [dep_jack]
if readline_support
  jack_transport_c_args += ['-DHAVE_READLINE']
  jack_transport_deps += [dep_readline]
endif

exe_jack_transport = executable(
  'jack_transport',
  c_args: jack_transport_c_args,
  sources: ['transport.c'],
  dependencies: jack_transport_deps,
  install: true
)

exe_jack_tw = executable(
  'jack_tw',
  sources: ['tw.c'],
  dependencies: [dep_jack],
  install: true
)

exe_jack_wait = executable(
  'jack_wait',
  c_args: c_args_common,
  sources: ['wait.c'],
  dependencies: [dep_jack],
  install: true
)

if build_zalsa
  subdir('zalsa')
endif
07070100000052000081A400000000000000000000000161E2F7EE0000163D000000000000000000000000000000000000002700000000jack-example-tools-1/tools/midi_dump.c// gcc -o jack_midi_dump -Wall midi_dump.c -ljack -pthread

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <inttypes.h>
#include <jack/jack.h>
#include <jack/midiport.h>
#include <jack/ringbuffer.h>

#ifdef __MINGW32__
#include <pthread.h>
#endif

#ifndef WIN32
#include <signal.h>
#include <pthread.h>
#include <sys/mman.h>
#endif

static jack_port_t* port;
static jack_ringbuffer_t *rb = NULL;
static pthread_mutex_t msg_thread_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER;

static int keeprunning = 1;
static uint64_t monotonic_cnt = 0;

#define RBSIZE 100
#define MSG_BUFFER_SIZE 4096

typedef struct {
	uint8_t  buffer[MSG_BUFFER_SIZE];
	uint32_t size;
	uint32_t tme_rel;
	uint64_t tme_mon;
} midimsg;

static void
describe (midimsg* event)
{
	if (event->size == 0) {
		return;
	}

	uint8_t type = event->buffer[0] & 0xf0;
	uint8_t channel = event->buffer[0] & 0xf;

	switch (type) {
		case 0x90:
			assert (event->size == 3);
			printf (" note on  (channel %2d): pitch %3d, velocity %3d", channel, event->buffer[1], event->buffer[2]);
			break;
		case 0x80:
			assert (event->size == 3);
			printf (" note off (channel %2d): pitch %3d, velocity %3d", channel, event->buffer[1], event->buffer[2]);
			break;
		case 0xb0:
			assert (event->size == 3);
			printf (" control change (channel %2d): controller %3d, value %3d", channel, event->buffer[1], event->buffer[2]);
			break;
		default:
			break;
	}
}

int
process (jack_nframes_t frames, void* arg)
{
	void* buffer;
	jack_nframes_t N;
	jack_nframes_t i;

	buffer = jack_port_get_buffer (port, frames);
	assert (buffer);
	
	N = jack_midi_get_event_count (buffer);
	for (i = 0; i < N; ++i) {
		jack_midi_event_t event;
		int r;
		r = jack_midi_event_get (&event, buffer, i);

		if (r != 0) {continue;}

		if (event.size > MSG_BUFFER_SIZE) {
			fprintf(stderr, "Error: MIDI message was too large, skipping event. Max. allowed size: %d bytes\n", MSG_BUFFER_SIZE);
		}
		else if (jack_ringbuffer_write_space (rb) >= sizeof(midimsg)) {
			midimsg m;
			m.tme_mon = monotonic_cnt;
			m.tme_rel = event.time;
			m.size    = event.size;
			memcpy (m.buffer, event.buffer, event.size);
			jack_ringbuffer_write (rb, (void *) &m, sizeof(midimsg));
		}
		else {
			fprintf (stderr, "Error: ringbuffer was full, skipping event.\n");
		}
	}

	monotonic_cnt += frames;

	if (pthread_mutex_trylock (&msg_thread_lock) == 0) {
		pthread_cond_signal (&data_ready);
		pthread_mutex_unlock (&msg_thread_lock);
	}

	return 0;
}

static void wearedone(int sig) {
	fprintf(stderr, "Shutting down\n");
	keeprunning = 0;
	/* main loop might be blocked by data_ready when jack server dies. */
	if (pthread_mutex_trylock (&msg_thread_lock) == 0) {
		pthread_cond_signal (&data_ready);
		pthread_mutex_unlock (&msg_thread_lock);
	}
}

static void usage (int status) {
	printf ("jack_midi_dump - JACK MIDI Monitor.\n\n");
	printf ("Usage: jack_midi_dump [ OPTIONS ] [CLIENT-NAME]\n\n");
	printf ("Options:\n\
  -a        use absolute timestamps relative to application start\n\
  -h        display this help and exit\n\
  -r        use relative timestamps to previous MIDI event\n\
\n");
	printf ("\n\
This tool listens for MIDI events on a JACK MIDI port and prints\n\
the message to stdout.\n\
\n\
If no client name is given it defaults to 'midi-monitor'.\n\
\n\
See also: jackd(1)\n\
\n");
	exit (status);
}

int
main (int argc, char* argv[])
{
	jack_client_t* client;
	char const default_name[] = "midi-monitor";
	char const * client_name;
	int time_format = 0;
	int r;

	int cn = 1;

	if (argc > 1) {
		if      (!strcmp (argv[1], "-a")) { time_format = 1; cn = 2; }
		else if (!strcmp (argv[1], "-r")) { time_format = 2; cn = 2; }
		else if (!strcmp (argv[1], "-h")) { usage (EXIT_SUCCESS); }
		else if (argv[1][0] == '-')       { usage (EXIT_FAILURE); }
	}

	if (argc > cn) {
		client_name = argv[cn];
	} else {
		client_name = default_name;
	}

	client = jack_client_open (client_name, JackNullOption, NULL);
	if (client == NULL) {
		fprintf (stderr, "Could not create JACK client.\n");
		exit (EXIT_FAILURE);
	}

	rb = jack_ringbuffer_create (RBSIZE * sizeof(midimsg));

	jack_set_process_callback (client, process, 0);

	port = jack_port_register (client, "input", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
	if (port == NULL) {
		fprintf (stderr, "Could not register port.\n");
		exit (EXIT_FAILURE);
	}

#ifndef WIN32
	if (mlockall (MCL_CURRENT | MCL_FUTURE)) {
		fprintf (stderr, "Warning: Can not lock memory.\n");
	}
#endif

	r = jack_activate (client);
	if (r != 0) {
		fprintf (stderr, "Could not activate client.\n");
		exit (EXIT_FAILURE);
	}

#ifndef WIN32
	signal(SIGHUP, wearedone);
	signal(SIGINT, wearedone);
#endif

	pthread_mutex_lock (&msg_thread_lock);

	uint64_t prev_event = 0;
	while (keeprunning) {
		const int mqlen = jack_ringbuffer_read_space (rb) / sizeof(midimsg);
		int i;
		for (i=0; i < mqlen; ++i) {
			size_t j;
			midimsg m;
			jack_ringbuffer_read(rb, (char*) &m, sizeof(midimsg));

			switch(time_format) {
				case 1:
					printf ("%7"PRId64":", m.tme_rel + m.tme_mon);
					break;
				case 2:
					printf ("%+6"PRId64":", m.tme_rel + m.tme_mon - prev_event);
					break;
				default:
					printf ("%4d:", m.tme_rel);
					break;
			}
			for (j = 0; j < m.size && j < sizeof(m.buffer); ++j) {
				printf (" %02x", m.buffer[j]);
			}

			describe (&m);
			printf("\n");
			prev_event = m.tme_rel + m.tme_mon;
		}
		fflush (stdout);
		pthread_cond_wait (&data_ready, &msg_thread_lock);
	}
	pthread_mutex_unlock (&msg_thread_lock);

	jack_deactivate (client);
	jack_client_close (client);
	jack_ringbuffer_free (rb);

	return 0;
}
07070100000053000081A400000000000000000000000161E2F7EE0000068A000000000000000000000000000000000000002C00000000jack-example-tools-1/tools/monitor_client.c/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <jack/jack.h>

#define TRUE 1
#define FALSE 0

int
main (int argc, char *argv[])
{
	jack_client_t *client;
	char *my_name = strrchr(argv[0], '/');

	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	if (argc != 2) {
		fprintf (stderr, "Usage: %s client\n", my_name);
		return 1;
	}

	if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}

	if (jack_port_request_monitor_by_name (client, argv[1], TRUE)) {
		fprintf (stderr, "could not enable monitoring for %s\n", argv[1]);
		jack_client_close (client);
		return 1;
	}

#ifdef WIN32
	Sleep (30*1000);
#else
	sleep (30);
#endif
	if (jack_port_request_monitor_by_name (client, argv[1], FALSE)) {
		fprintf (stderr, "could not disable monitoring for %s\n", argv[1]);
	}
	jack_client_close (client);
	exit (0);
}

07070100000054000081A400000000000000000000000161E2F7EE000064FE000000000000000000000000000000000000002700000000jack-example-tools-1/tools/netsource.c/*
NetJack Client

Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org>
Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

/** @file netsource.c
 *
 * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master
 */


#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#ifdef WIN32
#include <winsock2.h>
#define socklen_t int
#include <malloc.h>
#else
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#endif

/* These two required by FreeBSD. */
#include <sys/types.h>

#include <jack/jack.h>

#include <netjack_packet.h>
#include <samplerate.h>

#ifndef CUSTOM_MODES
#define CUSTOM_MODES // for opus_custom_decoder_init
#endif

#if HAVE_OPUS
#include <opus/opus.h>
#include <opus/opus_custom.h>
#endif

#include <math.h>

JSList *capture_ports = NULL;
JSList *capture_srcs = NULL;
int capture_channels = 0;
int capture_channels_audio = 2;
int capture_channels_midi = 1;
JSList *playback_ports = NULL;
JSList *playback_srcs = NULL;
int playback_channels = 0;
int playback_channels_audio = 2;
int playback_channels_midi = 1;
int dont_htonl_floats = 0;

int latency = 5;
jack_nframes_t kbps = 0;
int bitdepth = 0;
int mtu = 1400;
int reply_port = 0;
int bind_port = 0;
int redundancy = 1;
jack_client_t *client;
packet_cache * packcache = 0;

int state_connected = 0;
int state_latency = 0;
int state_netxruns = 0;
int state_currentframe = 0;
int state_recv_packet_queue_time = 0;

int quit = 0;


int outsockfd;
int insockfd;
#ifdef WIN32
struct sockaddr_in destaddr;
struct sockaddr_in bindaddr;
#else
struct sockaddr destaddr;
struct sockaddr bindaddr;
#endif

int sync_state;
jack_transport_state_t last_transport_state;

int framecnt = 0;

int cont_miss = 0;

int freewheeling = 0;

/**
 * This Function allocates all the I/O Ports which are added the lists.
 */
void
alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
{

    int port_flags = JackPortIsOutput;
    int chn;
    jack_port_t *port;
    char buf[32];

    capture_ports = NULL;
    /* Allocate audio capture channels */
    for (chn = 0; chn < n_capture_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
        if (!port) {
            printf( "jack_netsource: cannot register %s port\n", buf);
            break;
        }
        if (bitdepth == 999) {
#if HAVE_OPUS
            int err;
            OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err);
            if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
            OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err);
            if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); }
            opus_custom_decoder_init(decoder, opus_mode, 1);
            capture_srcs = jack_slist_append(capture_srcs, decoder);
#endif
        } else {
            capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
        }
        capture_ports = jack_slist_append (capture_ports, port);
    }

    /* Allocate midi capture channels */
    for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        capture_ports = jack_slist_append(capture_ports, port);
    }

    /* Allocate audio playback channels */
    port_flags = JackPortIsInput;
    playback_ports = NULL;
    for (chn = 0; chn < n_playback_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        if( bitdepth == 999 ) {
#if HAVE_OPUS
            printf("new opus encoder %d kbps\n", kbps);
            int err;
            OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me
            if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
            OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
            if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); }
            opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
            opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
            opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
            opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
            opus_custom_encoder_init(oe, opus_mode, 1);
            playback_srcs = jack_slist_append(playback_srcs, oe);
#endif
        } else {
            playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
        }
        playback_ports = jack_slist_append (playback_ports, port);
    }

    /* Allocate midi playback channels */
    for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        playback_ports = jack_slist_append (playback_ports, port);
    }
}

/**
 * The Sync callback... sync state is set elsewhere...
 * we will see if this is working correctly.
 * i don't really believe in it yet.
 */
int
sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
{
    static int latency_count = 0;
    int retval = sync_state;

    if (! state_connected) {
        return 1;
    }
    if (latency_count) {
        latency_count--;
        retval = 0;
    }

    else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
        retval = 0;
        latency_count = latency - 1;
    }

    last_transport_state = state;
    return retval;
}

void
freewheel_cb (int starting, void *arg)
{
    freewheeling = starting;
}

int deadline_goodness = 0;
/**
 * The process callback for this JACK application.
 * It is called by JACK at the appropriate times.
 */
int
process (jack_nframes_t nframes, void *arg)
{
    jack_nframes_t net_period;
    int rx_bufsize, tx_bufsize;

    jack_default_audio_sample_t *buf;
    jack_port_t *port;
    JSList *node;
    int chn;
    int size, i;
    const char *porttype;
    int input_fd;

    jack_position_t local_trans_pos;

    uint32_t *packet_buf_tx, *packet_bufX;
    uint32_t *rx_packet_ptr;
    jack_time_t packet_recv_timestamp;

    if( bitdepth == 999)
        net_period = (kbps * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
    else
        net_period = (float) nframes;

    rx_bufsize =  get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
    tx_bufsize =  get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);

    /* Allocate a buffer where both In and Out Buffer will fit */
    packet_buf_tx = alloca (tx_bufsize);

    jacknet_packet_header *pkthdr_tx = (jacknet_packet_header *) packet_buf_tx;

    /*
     * for latency==0 we need to send out the packet before we wait on the reply.
     * but this introduces a cycle of latency, when netsource is connected to itself.
     * so we send out before read only in zero latency mode.
     *
     */

    if( latency == 0 ) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    /*
     * ok... now the RECEIVE code.
     *
     */


    if( reply_port )
        input_fd = insockfd;
    else
        input_fd = outsockfd;

    // for latency == 0 we can poll.
    if( (latency == 0) || (freewheeling != 0)  ) {
        jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client);
        // Now loop until we get the right packet.
        while(1) {
            jack_nframes_t got_frame;
            if ( ! netjack_poll_deadline( input_fd, deadline ) )
                break;

            packet_cache_drain_socket(packcache, input_fd);

            if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame ))
                if( got_frame == (framecnt - latency) )
                    break;
        }
    } else {
        // normally:
        // only drain socket.
        packet_cache_drain_socket(packcache, input_fd);
    }

    size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
    /* First alternative : we received what we expected. Render the data
     * to the JACK ports so it can be played. */
    if (size == rx_bufsize) {
        uint32_t *packet_buf_rx = rx_packet_ptr;
        jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx;
        packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
        // calculate how much time there would have been, if this packet was sent at the deadline.

        int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
        packet_header_ntoh (pkthdr_rx);
        deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency;
        //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );

        if (cont_miss) {
            //printf("Frame %d  \tRecovered from dropouts\n", framecnt);
            cont_miss = 0;
        }
        render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
                                      capture_ports, capture_srcs, nframes, dont_htonl_floats);

        state_currentframe = framecnt;
        state_recv_packet_queue_time = recv_time_offset;
        state_connected = 1;
        sync_state = pkthdr_rx->sync_state;
        packet_cache_release_packet( packcache, framecnt - latency );
    }
    /* Second alternative : we've received something that's not
     * as big as expected or we missed a packet. We render silence
     * to the output ports */
    else {
        jack_nframes_t latency_estimate;
        if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) )
            //if( (state_latency == 0) || (latency_estimate < state_latency) )
            state_latency = latency_estimate;

        // Set the counters up.
        state_currentframe = framecnt;
        //state_latency = framecnt - pkthdr->framecnt;
        state_netxruns += 1;

        //printf ("Frame %d  \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
        //printf ("Frame %d  \tPacket missed or incomplete\n", framecnt);
        cont_miss += 1;
        chn = 0;
        node = capture_ports;
        while (node != NULL) {
            port = (jack_port_t *) node->data;
            buf = jack_port_get_buffer (port, nframes);
            porttype = jack_port_type (port);
            if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
                for (i = 0; i < nframes; i++)
                    buf[i] = 0.0;
            else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
                jack_midi_clear_buffer (buf);
            node = jack_slist_next (node);
            chn++;
        }
    }
    if (latency != 0) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    framecnt++;
    return 0;
}

/**
 * This is the shutdown callback for this JACK application.
 * It is called by JACK if the server ever shuts down or
 * decides to disconnect the client.
 */

void
jack_shutdown (void *arg)
{
    fprintf(stderr, "JACK shut down, exiting ...\n");
    exit (1);
}

void
init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
{
    name->sin_family = AF_INET ;
    name->sin_port = htons (port);
    if (hostname) {
        struct hostent *hostinfo = gethostbyname (hostname);
        if (hostinfo == NULL) {
            fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
            fflush( stderr );
        }
#ifdef WIN32
        name->sin_addr.s_addr = inet_addr( hostname );
#else
        name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
#endif
    } else
        name->sin_addr.s_addr = htonl (INADDR_ANY) ;

}

void
printUsage ()
{
    fprintf (stderr, "usage: jack_netsource [options]\n"
             "\n"
             "  -h this help text\n"
             "  -H <slave host> - Host name of the slave JACK\n"
             "  -o <num channels> - Number of audio playback channels\n"
             "  -i <num channels> - Number of audio capture channels\n"
             "  -O <num channels> - Number of midi playback channels\n"
             "  -I <num channels> - Number of midi capture channels\n"
             "  -n <periods> - Network latency in JACK periods\n"
             "  -p <port> - UDP port that the slave is listening on\n"
             "  -r <reply port> - UDP port that we are listening on\n"
             "  -B <bind port> - reply port, for use in NAT environments\n"
             "  -b <bitdepth> - Set transport to use 16bit or 8bit\n"
             "  -P <kbits> - Use Opus encoding with <kbits> kbits per channel\n"
             "  -m <mtu> - Assume this mtu for the link\n"
             "  -R <N> - Redundancy: send out packets N times.\n"
             "  -e - skip host-to-network endianness conversion\n"
             "  -N <jack name> - Reports a different name to jack\n"
             "  -s <server name> - The name of the local jack server\n"
             "\n");
}

void
sigterm_handler( int signal )
{
    quit = 1;
}

int
main (int argc, char *argv[])
{
    /* Some startup related basics */
    char *client_name, *server_name = NULL, *peer_ip;
    int peer_port = 3000;
    jack_options_t options = JackNullOption;
    jack_status_t status;
#ifdef WIN32
    WSADATA wsa;
    int rc = WSAStartup(MAKEWORD(2, 0), &wsa);
#endif
    /* Torben's famous state variables, aka "the reporting API" ! */
    /* heh ? these are only the copies of them ;)                 */
    int statecopy_connected, statecopy_latency, statecopy_netxruns;
    jack_nframes_t net_period;
    /* Argument parsing stuff */
    extern char *optarg;
    extern int optind, optopt;
    int errflg = 0, c;

    if (argc < 3) {
        printUsage ();
        return 1;
    }

    client_name = (char *) malloc (sizeof (char) * 10);
    peer_ip = (char *) malloc (sizeof (char) * 10);
    sprintf(client_name, "netjack");
    sprintf(peer_ip, "localhost");

    while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) {
        switch (c) {
            case 'h':
                printUsage();
                exit (0);
                break;
            case 'H':
                free(peer_ip);
                peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (peer_ip, optarg);
                break;
            case 'o':
                playback_channels_audio = atoi (optarg);
                break;
            case 'i':
                capture_channels_audio = atoi (optarg);
                break;
            case 'O':
                playback_channels_midi = atoi (optarg);
                break;
            case 'I':
                capture_channels_midi = atoi (optarg);
                break;
            case 'n':
                latency = atoi (optarg);
                break;
            case 'p':
                peer_port = atoi (optarg);
                break;
            case 'r':
                reply_port = atoi (optarg);
                break;
            case 'B':
                bind_port = atoi (optarg);
                break;
            case 'b':
                bitdepth = atoi (optarg);
                break;
            case 'P':
#if HAVE_OPUS
                bitdepth = 999;
                kbps = atoi (optarg);
#else
                printf( "not built with opus support\n" );
                exit(10);
#endif
                break;
            case 'm':
                mtu = atoi (optarg);
                break;
            case 'R':
                redundancy = atoi (optarg);
                break;
            case 'e':
                dont_htonl_floats = 1;
                break;
            case 'N':
                free(client_name);
                client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (client_name, optarg);
                break;
            case 's':
                server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (server_name, optarg);
                options |= JackServerName;
                break;
            case ':':
                fprintf (stderr, "Option -%c requires an operand\n", optopt);
                errflg++;
                break;
            case '?':
                fprintf (stderr, "Unrecognized option: -%c\n", optopt);
                errflg++;
        }
    }
    if (errflg) {
        printUsage ();
        exit (2);
    }

    capture_channels = capture_channels_audio + capture_channels_midi;
    playback_channels = playback_channels_audio + playback_channels_midi;

    outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
    insockfd = socket (AF_INET, SOCK_DGRAM, 0);

    if ((outsockfd == -1) || (insockfd == -1)) {
        fprintf (stderr, "can not open sockets\n" );
        return 1;
    }

    init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
    if (bind_port) {
        init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port);
        if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) {
            fprintf (stderr, "bind failure\n" );
        }
    }
    if (reply_port) {
        init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
        if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
            fprintf (stderr, "bind failure\n" );
        }
    }

    /* try to become a client of the JACK server */
    client = jack_client_open (client_name, options, &status, server_name);
    if (client == NULL) {
        fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
                 "Is the JACK server running ?\n", status);
        return 1;
    }

    /* Set up jack callbacks */
    jack_set_process_callback (client, process, 0);
    jack_set_sync_callback (client, sync_cb, 0);
    jack_set_freewheel_callback (client, freewheel_cb, 0);
    jack_on_shutdown (client, jack_shutdown, 0);

    alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);

    if( bitdepth == 999)
        net_period = (kbps * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
    else
        net_period = ceilf((float) jack_get_buffer_size (client));

    int rx_bufsize =  get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
    packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);

    /* tell the JACK server that we are ready to roll */
    if (jack_activate (client)) {
        fprintf (stderr, "Cannot activate client");
        return 1;
    }

    /* Now sleep forever... and evaluate the state_ vars */

    signal( SIGTERM, sigterm_handler );
    signal( SIGINT, sigterm_handler );

    statecopy_connected = 2; // make it report unconnected on start.
    statecopy_latency = state_latency;
    statecopy_netxruns = state_netxruns;

    while ( !quit ) {
#ifdef WIN32
        Sleep (1000);
#else
        sleep(1);
#endif
        if (statecopy_connected != state_connected) {
            statecopy_connected = state_connected;
            if (statecopy_connected) {
                state_netxruns = 1; // We want to reset the netxrun count on each new connection
                printf ("Connected :-)\n");
            } else
                printf ("Not Connected\n");

            fflush(stdout);
        }

        if (statecopy_connected) {
            if (statecopy_netxruns != state_netxruns) {
                statecopy_netxruns = state_netxruns;
                printf ("%s: at frame %06d -> total netxruns %d  (%d%%) queue time= %d\n",
                        client_name,
                        state_currentframe,
                        statecopy_netxruns,
                        100 * statecopy_netxruns / state_currentframe,
                        state_recv_packet_queue_time);

                fflush(stdout);
            }
        } else {
            if (statecopy_latency != state_latency) {
                statecopy_latency = state_latency;
                if (statecopy_latency > 1)
                    printf ("current latency %d\n", statecopy_latency);
                fflush(stdout);
            }
        }
    }

    jack_client_close (client);
    packet_cache_free (packcache);
    exit (0);
}
07070100000055000081A400000000000000000000000161E2F7EE00001C0C000000000000000000000000000000000000002600000000jack-example-tools-1/tools/property.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>

#include <jack/jack.h>
#include <jack/metadata.h>
#include <jack/uuid.h>
#include <jack/session.h>

static int subject_is_client = 0;
static int subject_is_port = 0;
static jack_uuid_t uuid = JACK_UUID_EMPTY_INITIALIZER;
static char* subject = NULL;

static void
show_usage (void)
{
	fprintf (stderr, "\nUsage: jack_property [options] UUID [ key [ value [ type ] ] ]\n");
	fprintf (stderr, "Set/Display JACK properties (metadata).\n\n");
	fprintf (stderr, "Set options:\n");
	fprintf (stderr, "        -s, --set        Set property \"key\" to \"value\" for \"UUID\" with optional MIME type \"type\"\n");
	fprintf (stderr, "        -d, --delete     Remove/delete property \"key\" for \"UUID\"\n");
	fprintf (stderr, "        -d, --delete     UUID Remove/delete all properties for \"UUID\"\n");
	fprintf (stderr, "        -D, --delete-all Remove/delete all properties\n");
	fprintf (stderr, "        --client         Interpret UUID as a client name, not a UUID\n");
	fprintf (stderr, "        --port           Interpret UUID as a port name, not a UUID\n");
	fprintf (stderr, "\nDisplay options:\n");
	fprintf (stderr, "        -l                  Show all properties\n");
	fprintf (stderr, "        -l, --list UUID     Show value for all properties of UUID\n");
	fprintf (stderr, "        -l, --list UUID key Show value for key of UUID\n");
	fprintf (stderr, "\nFor more information see https://jackaudio.org/\n");
}

static int
get_subject (jack_client_t* client, char* argv[], int* optind)
{
	if (subject_is_client) {
		char* cstr = argv[(*optind)++];
		char* ustr;

		if ((ustr = jack_get_uuid_for_client_name (client, cstr)) == NULL) {
			fprintf (stderr, "cannot get UUID for client named %s\n", cstr);
			return -1;
		}

		if (jack_uuid_parse (ustr, &uuid)) {
			fprintf (stderr, "cannot parse client UUID as UUID '%s' '%s'\n", cstr, ustr);
			return -1;
		}

		subject = cstr;

	} else if (subject_is_port) {

		char* pstr = argv[(*optind)++];
		jack_port_t* port;

		if ((port = jack_port_by_name (client, pstr)) == NULL) {
			fprintf (stderr, "cannot find port name %s\n", pstr);
			return -1;
		}

		uuid = jack_port_uuid (port);
		subject = pstr;

	} else {
		char* str = argv[(*optind)++];

		if (jack_uuid_parse (str, &uuid)) {
			fprintf (stderr, "cannot parse subject as UUID\n");
			return -1;
		}

		subject = str;
	}

	return 0;
}

int main (int argc, char* argv[])
{
	jack_client_t* client = NULL;
	jack_options_t options = JackNoStartServer;
	char* key = NULL;
	char* value = NULL;
	char* type = NULL;
	int set = 1;
	int delete = 0;
	int delete_all = 0;
	int c;
	int option_index;
	extern int optind;
	struct option long_options[] = {
		{ "set", 0, 0, 's' },
		{ "delete", 0, 0, 'd' },
		{ "delete-all", 0, 0, 'D' },
		{ "list", 0, 0, 'l' },
		{ "client", 0, 0, 'c' },
		{ "port", 0, 0, 'p' },
		{ 0, 0, 0, 0 }
	};

	if (argc < 2) {
		show_usage ();
		exit (1);
	}

	while ((c = getopt_long (argc, argv, "sdDlApc", long_options, &option_index)) >= 0) {
		switch (c) {
		case 's':
			if (argc < 5) {
				show_usage ();
				exit (1);
			}
			set = 1;
			break;
		case 'd':
			if (argc < 3) {
				show_usage ();
				return 1;
			}
			set = 0;
			delete = 1;
			break;

		case 'D':
			delete = 0;
			set = 0;
			delete_all = 1;
			break;

		case 'l':
			set = 0;
			delete = 0;
			delete_all = 0;
			break;

		case 'p':
			subject_is_port = 1;
			break;

		case 'c':
			subject_is_client = 1;
			break;

		case '?':
		default:
			show_usage ();
			exit (1);
		}
	}

	if ((client = jack_client_open ("jack-property", options, NULL)) == 0) {
		fprintf (stderr, "Cannot connect to JACK server\n");
		exit (1);
	}

	if (delete_all) {

		if (jack_remove_all_properties (client) == 0) {
			printf ("JACK metadata successfully delete\n");
			exit (0);
		}
		exit (1);
	}

	if (delete) {

		int args_left = argc - optind;

		if (args_left < 1) {
			show_usage ();
			exit (1);
		}

		/* argc == 3: delete all properties for a subject
		   argc == 4: delete value of key for subject
		*/

		if (args_left >= 2) {

			if (get_subject (client, argv, &optind)) {
				return 1;
			}

			key = argv[optind++];

			if (jack_remove_property (client, uuid, key)) {
				fprintf (stderr, "\"%s\" property not removed for %s\n", key, subject);
				exit (1);
			}

		} else {

			if (get_subject (client, argv, &optind)) {
				return 1;
			}

			if (jack_remove_properties (client, uuid) < 0) {
				fprintf (stderr, "cannot remove properties for UUID %s\n", subject);
				exit (1);
			}
		}

	}  else if (set) {

		int args_left = argc - optind;

		if (get_subject (client, argv, &optind)) {
			return -1;
		}

		key = argv[optind++];
		value = argv[optind++];

		if (args_left >= 3) {
			type = argv[optind++];
		} else {
			type = "";
		}

		if (jack_set_property (client, uuid, key, value, type)) {
			fprintf (stderr, "cannot set value for key %s of %s\n", key, subject);
			exit (1);
		}

	} else {

		/* list properties */

		int args_left = argc - optind;

		if (args_left >= 2) {

			/* list properties for a UUID/key pair */

			if (get_subject (client, argv, &optind)) {
				return -1;
			}

			key = argv[optind++];

			if (jack_get_property (uuid, key, &value, &type) == 0) {
				printf ("%s\n", value);
				free (value);
				if (type) {
					free (type);
				}
			} else {
				fprintf (stderr, "Value not found for %s of %s\n", key, subject);
				exit (1);
			}

		} else if (args_left == 1) {

			/* list all properties for a given UUID */

			jack_description_t description;
			int cnt, n;

			if (get_subject (client, argv, &optind)) {
				return -1;
			}

			if ((cnt = jack_get_properties (uuid, &description)) < 0) {
				fprintf (stderr, "could not retrieve properties for %s\n", subject);
				exit (1);
			}

			for (n = 0; n < cnt; ++n) {
				if (description.properties[n].type) {
					printf ("key: %s value: %s type: %s\n",
						description.properties[n].key,
						description.properties[n].data,
						description.properties[n].type);
				} else {
					printf ("key: %s value: %s\n",
						description.properties[n].key,
						description.properties[n].data);
				}
			}

			jack_free_description (&description, 0);

		} else {

			/* list all properties */

			jack_description_t* description;
			int cnt, n;
			size_t p;
			char buf[JACK_UUID_STRING_SIZE];

			if ((cnt = jack_get_all_properties (&description)) < 0) {
				fprintf (stderr, "could not retrieve all properties\n");
				exit (1);
			}

			for (n = 0; n < cnt; ++n) {
				jack_uuid_unparse (description[n].subject, buf);
				printf ("%s\n", buf);
				for (p = 0; p < description[n].property_cnt; ++p) {
					if (description[n].properties[p].type) {
						printf ("key: %s value: %s type: %s\n",
							description[n].properties[p].key,
							description[n].properties[p].data,
							description[n].properties[p].type);
					} else {
						printf ("key: %s value: %s\n",
							description[n].properties[p].key,
							description[n].properties[p].data);
					}
				}
				jack_free_description (&description[n], 0);
			}

			free (description);
		}
	}

	jack_client_close (client);
	return 0;
}
07070100000056000081A400000000000000000000000161E2F7EE00000806000000000000000000000000000000000000002800000000jack-example-tools-1/tools/samplerate.c/*
 *  smaplerate.c -- get current samplerate
 *
 *  Copyright (C) 2003 Jack O'Quin.
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include <jack/transport.h>

char *package;				/* program name */
jack_client_t *client;

void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

void parse_arguments(int argc, char *argv[])
{

	/* basename $0 */
	package = strrchr(argv[0], '/');
	if (package == 0)
		package = argv[0];
	else
		package++;

	if (argc==1) {
		return;
	}
	fprintf(stderr, "usage: %s\n", package);
	exit(9);
}

int main(int argc, char *argv[])
{
	parse_arguments(argc, argv);

	/* become a JACK client */
	if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) {
		fprintf(stderr, "JACK server not running?\n");
		exit(1);
	}

#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	fprintf(stdout, "%d\n", jack_get_sample_rate( client ) );

	jack_client_close(client);

	return 0;
}
07070100000057000081A400000000000000000000000161E2F7EE0000125E000000000000000000000000000000000000002C00000000jack-example-tools-1/tools/session_notify.c/*
 *  session_notify.c -- ultra minimal session manager
 *
 *  Copyright (C) 2018 Karl Linden <karl.j.linden@gmail.com>
 *  Copyright (C) 2010 Torben Hohn.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <alloca.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <jack/jack.h>
#include <jack/jslist.h>
#include <jack/transport.h>
#include <jack/session.h>

char *package;				/* program name */
jack_client_t *client;

jack_session_event_type_t notify_type;
char *save_path = NULL;

void jack_shutdown(void *arg)
{
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

void parse_arguments(int argc, char *argv[])
{

	/* basename $0 */
	package = strrchr(argv[0], '/');
	if (package == 0)
		package = argv[0];
	else
		package++;

	if (argc==2) {
		if( !strcmp( argv[1], "quit" ) ) {
			notify_type = JackSessionSaveAndQuit;
			return;
		}
	}
	if (argc==3) {
		if( !strcmp( argv[1], "save" ) ) {
			notify_type = JackSessionSave;
			save_path = argv[2];
			return;
		}

	}
	fprintf(stderr, "usage: %s quit|save [path]\n", package);
	exit(9);
}

typedef struct {
	char name[32];
	char uuid[16];
} uuid_map_t;

JSList *uuid_map = NULL;

void add_uuid_mapping( const char *uuid ) {
	char *clientname = jack_get_client_name_by_uuid( client, uuid );
	if( !clientname ) {
		printf( "error... can not find client for uuid" );
		return;
	}

	uuid_map_t *mapping = malloc( sizeof(uuid_map_t) );
	snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid );
	snprintf( mapping->name, sizeof(mapping->name), "%s", clientname );
	uuid_map = jack_slist_append( uuid_map, mapping );
}

char *map_port_name_to_uuid_port( const char *port_name )
{
	JSList *node;
	char retval[300];
	char *port_component = strchr( port_name,':' );
	char *client_component = strdup( port_name );
	strchr( client_component, ':' )[0] = '\0';

	sprintf( retval, "%s", port_name );

	for( node=uuid_map; node; node=jack_slist_next(node) ) {
		uuid_map_t *mapping = node->data;
		if( !strcmp( mapping->name, client_component ) ) {
			sprintf( retval, "%s%s", mapping->uuid, port_component );
			break;
		}
	}

	return strdup(retval);
}

int main(int argc, char *argv[])
{
	parse_arguments(argc, argv);
	jack_session_command_t *retval;
	int k,i,j;


	/* become a JACK client */
	if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) {
		fprintf(stderr, "JACK server not running?\n");
		exit(1);
	}

#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif

	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	jack_activate(client);


	retval = jack_session_notify( client, NULL, notify_type, save_path );
	for (i = 0; retval[i].uuid; i++) {
		printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name );
		printf( "%s &\n", retval[i].command );
		add_uuid_mapping(retval[i].uuid);
	}

	printf( "sleep 10\n" );

	for (k = 0; retval[k].uuid; k++) {

		char* port_regexp = alloca( jack_client_name_size()+3 );
		char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid );
		snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name );
		jack_free(client_name);
		const char **ports = jack_get_ports( client, port_regexp, NULL, 0 );
		if( !ports ) {
			continue;
		}
		for (i = 0; ports[i]; ++i) {
			const char **connections;
			if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) {
				for (j = 0; connections[j]; j++) {
					char *src = map_port_name_to_uuid_port( ports[i] );
					char *dst = map_port_name_to_uuid_port( connections[j] );
					printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst );
				}
				jack_free (connections);
			}
		}
		jack_free(ports);

	}
	jack_session_commands_free(retval);

	jack_client_close(client);

	return 0;
}
07070100000058000081A400000000000000000000000161E2F7EE00003133000000000000000000000000000000000000002700000000jack-example-tools-1/tools/transport.c/*
 *  transport.c -- JACK transport master example client.
 *
 *  Copyright (C) 2003 Jack O'Quin.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif
#include <jack/jack.h>
#include <jack/transport.h>

/* Use a copy of the readline macro whitespace if it does not exist.
 * Not all readline compatible libraries supply the whitespace macro
 * (libedit for example), so pull in the copy in those cases too. */
#if !HAVE_READLINE || !defined(whitespace)
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif

char *package;				/* program name */
int done = 0;
jack_client_t *client;
double last_tick;

/* Time and tempo variables.  These are global to the entire,
 * transport timeline.  There is no attempt to keep a true tempo map.
 * The default time signature is: "march time", 4/4, 120bpm
 */
float time_beats_per_bar = 4.0;
float time_beat_type = 4.0;
double time_ticks_per_beat = 1920.0;
double time_beats_per_minute = 120.0;
volatile int time_reset = 1;		/* true when time values change */
volatile int avr_set = 0;
float audio_frames_per_video_frame;

/* JACK timebase callback.
 *
 * Runs in the process thread.  Realtime, must not wait.
 */
static void timebase(jack_transport_state_t state, jack_nframes_t nframes,
                     jack_position_t *pos, int new_pos, void *arg)
{
	double min;			/* minutes since frame 0 */
	long abs_tick;			/* ticks since frame 0 */
	long abs_beat;			/* beats since frame 0 */

	if (new_pos || time_reset) {

		pos->valid = JackPositionBBT;
		pos->beats_per_bar = time_beats_per_bar;
		pos->beat_type = time_beat_type;
		pos->ticks_per_beat = time_ticks_per_beat;
		pos->beats_per_minute = time_beats_per_minute;

		time_reset = 0;		/* time change complete */

		/* Compute BBT info from frame number.  This is relatively
		 * simple here, but would become complex if we supported tempo
		 * or time signature changes at specific locations in the
		 * transport timeline. */

		min = pos->frame / ((double) pos->frame_rate * 60.0);
		abs_tick = min * pos->beats_per_minute * pos->ticks_per_beat;
		abs_beat = abs_tick / pos->ticks_per_beat;

		pos->bar = abs_beat / pos->beats_per_bar;
		pos->beat = abs_beat - (pos->bar * pos->beats_per_bar) + 1;
		last_tick = abs_tick - (abs_beat * pos->ticks_per_beat);
		pos->bar_start_tick = pos->bar * pos->beats_per_bar *
			pos->ticks_per_beat;
		pos->bar++;		/* adjust start to bar 1 */

#if 0
		/* some debug code... */
		fprintf(stderr, "\nnew position: %" PRIu32 "\tBBT: %3"
			PRIi32 "|%" PRIi32 "|%04" PRIi32 "\n",
			pos->frame, pos->bar, pos->beat, last_tick);
#endif

	} else {

		/* Compute BBT info based on previous period. */
		last_tick +=
			nframes * pos->ticks_per_beat * pos->beats_per_minute
			/ (pos->frame_rate * 60);

		while (last_tick >= pos->ticks_per_beat) {
			last_tick -= pos->ticks_per_beat;
			if (++pos->beat > pos->beats_per_bar) {
				pos->beat = 1;
				++pos->bar;
				pos->bar_start_tick +=
					pos->beats_per_bar
					* pos->ticks_per_beat;
			}
		}
	}

	pos->tick = (int)(last_tick + 0.5);

#ifdef JACK_TICK_DOUBLE
	pos->valid |= JackTickDouble;
	pos->tick_double = last_tick;
#endif

	if (avr_set) {
		pos->valid |= JackAudioVideoRatio;
		pos->audio_frames_per_video_frame = audio_frames_per_video_frame;
	}
}

static int jack_process(jack_nframes_t nframes, void *arg)
{
	return 0;
}

static void jack_shutdown(void *arg)
{
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0400
	rl_cleanup_after_signal();
#endif
	fprintf(stderr, "JACK shut down, exiting ...\n");
	exit(1);
}

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

/* Command functions: see commands[] table following. */

static void com_activate(char *arg)
{
	if (jack_activate(client)) {
		fprintf(stderr, "cannot activate client");
	}
}

static void com_deactivate(char *arg)
{
	if (jack_deactivate(client)) {
		fprintf(stderr, "cannot deactivate client");
	}
}

static void com_exit(char *arg)
{
	done = 1;
}

static void com_help(char *);			/* forward declaration */

static void com_locate(char *arg)
{
	jack_nframes_t frame = 0;

	if (*arg != '\0')
		frame = atoi(arg);

	jack_transport_locate(client, frame);
}

static void com_master(char *arg)
{
	int cond = (*arg != '\0');
	if (jack_set_timebase_callback(client, cond, timebase, NULL) != 0)
		fprintf(stderr, "Unable to take over timebase.\n");
}

static void com_play(char *arg)
{
	jack_transport_start(client);
}

static void com_release(char *arg)
{
	jack_release_timebase(client);
}

static void com_stop(char *arg)
{
	jack_transport_stop(client);
}

/* Change the tempo for the entire timeline, not just from the current
 * location. */
static void com_tempo(char *arg)
{
	float tempo = 120.0;

	if (*arg != '\0')
		tempo = atof(arg);

	time_beats_per_minute = tempo;
	time_reset = 1;
}

/* Set sync timeout in seconds. */
static void com_timeout(char *arg)
{
	double timeout = 2.0;

	if (*arg != '\0')
		timeout = atof(arg);

	jack_set_sync_timeout(client, (jack_time_t) (timeout*1000000));
}

/* Toggle between play and stop state */
static void com_toggle(char *arg)
{
	jack_position_t current;
	jack_transport_state_t transport_state;

	transport_state = jack_transport_query (client, &current);

	switch (transport_state) {
	case JackTransportStopped:
		com_play( arg );
		break;
	case JackTransportRolling:
		com_stop( arg );
		break;
	case JackTransportStarting:
		fprintf(stderr, "state: Starting - no transport toggling");
		break;
	default:
		fprintf(stderr, "unexpected state: no transport toggling");
	}
}

/* Change the tempo for the entire timeline, not just from the current
 * location. */
void com_av_ratio(char *arg)
{
	float avr = 0;

	if (*arg != '\0')
		avr = atof(arg);

	audio_frames_per_video_frame = avr;
	avr_set = 1;
}


/* Command parsing based on GNU readline info examples. */

typedef void cmd_function_t(char *);	/* command function type */

/* Transport command table. */
typedef struct {
	char *name;			/* user printable name */
	cmd_function_t *func;		/* function to call */
	char *doc;			/* documentation  */
} command_t;

/* command table must be in alphabetical order */
command_t commands[] = {
	{"activate",	com_activate,	"Call jack_activate()"},
	{"avr",	        com_av_ratio,	"Set audio/video frame ratio <audio frames per video frame>"},
	{"exit",	com_exit,	"Exit transport program"},
	{"deactivate",	com_deactivate,	"Call jack_deactivate()"},
	{"help",	com_help,	"Display help text [<command>]"},
	{"locate",	com_locate,	"Locate to frame <position>"},
	{"master",	com_master,	"Become timebase master "
					"[<conditionally>]"},
	{"play",	com_play,	"Start transport rolling"},
	{"quit",	com_exit,	"Synonym for `exit'"},
	{"release",	com_release,	"Release timebase"},
	{"stop",	com_stop,	"Stop transport"},
	{"tempo",	com_tempo,	"Set beat tempo <beats_per_min>"},
	{"timeout",	com_timeout,	"Set sync timeout in <seconds>"},
	{"toggle",	com_toggle,	"Toggle transport rolling"},
	{"?",		com_help,	"Synonym for `help'" },
	{(char *)NULL, (cmd_function_t *)NULL, (char *)NULL }
};

static command_t *find_command(char *name)
{
	register int i;
	size_t namelen;

	if ((name == NULL) || (*name == '\0'))
		return ((command_t *)NULL);

	namelen = strlen(name);
	for (i = 0; commands[i].name; i++)
		if (strncmp(name, commands[i].name, namelen) == 0) {

			/* make sure the match is unique */
			if ((commands[i+1].name) &&
				(strncmp(name, commands[i+1].name, namelen) == 0))
				return ((command_t *)NULL);
			else
				return (&commands[i]);
		}

	return ((command_t *)NULL);
}

static void com_help(char *arg)
{
	register int i;
	command_t *cmd;

	if (!*arg) {
		/* print help for all commands */
		for (i = 0; commands[i].name; i++) {
			printf("%s\t\t%s.\n", commands[i].name,
			       commands[i].doc);
		}

	} else if ((cmd = find_command(arg))) {
		printf("%s\t\t%s.\n", cmd->name, cmd->doc);

	} else {
		int printed = 0;

		printf("No `%s' command.  Valid command names are:\n", arg);

		for (i = 0; commands[i].name; i++) {
			/* Print in six columns. */
			if (printed == 6) {
				printed = 0;
				printf ("\n");
			}

			printf ("%s\t", commands[i].name);
			printed++;
		}

		printf("\n\nTry `help [command]\' for more information.\n");
	}
}

static void execute_command(char *line)
{
	register int i;
	command_t *command;
	char *word;

	/* Isolate the command word. */
	i = 0;
	while (line[i] && whitespace(line[i]))
		i++;
	word = line + i;

	while (line[i] && !whitespace(line[i]))
		i++;

	if (line[i])
		line[i++] = '\0';

	command = find_command(word);

	if (!command) {
		fprintf(stderr, "%s: No such command.  There is `help\'.\n",
			word);
		return;
	}

	/* Get argument to command, if any. */
	while (whitespace(line[i]))
		i++;

	word = line + i;

	/* invoke the command function. */
	(*command->func)(word);
}


/* Strip whitespace from the start and end of string. */
static char *stripwhite(char *string)
{
	register char *s, *t;

	s = string;
	while (whitespace(*s))
		s++;

	if (*s == '\0')
		return s;

	t = s + strlen (s) - 1;
	while (t > s && whitespace(*t))
		t--;
	*++t = '\0';

	return s;
}

static char *dupstr(char *s)
{
	char *r = malloc(strlen(s) + 1);
	strcpy(r, s);
	return r;
}

/* Readline generator function for command completion. */
static char *command_generator (const char *text, int state)
{
	static int list_index, len;
	char *name;

	/* If this is a new word to complete, initialize now.  This
	   includes saving the length of TEXT for efficiency, and
	   initializing the index variable to 0. */
	if (!state) {
		list_index = 0;
		len = strlen (text);
	}

	/* Return the next name which partially matches from the
	   command list. */
	while ((name = commands[list_index].name)) {
		list_index++;

		if (strncmp(name, text, len) == 0)
			return dupstr(name);
	}

	return (char *) NULL;		/* No names matched. */
}

static void command_loop()
{
#if HAVE_READLINE
	char *line, *cmd;
	char prompt[32];

	snprintf(prompt, sizeof(prompt), "%s> ", package);

	/* Allow conditional parsing of the ~/.inputrc file. */
	rl_readline_name = package;

	/* Define a custom completion function. */
	rl_completion_entry_function = command_generator;
#else
	char line[64] = {0,};
	char *cmd = NULL;
#endif

	/* Read and execute commands until the user quits. */
	while (!done) {

#if HAVE_READLINE
		line = readline(prompt);

		if (line == NULL) {	/* EOF? */
			printf("\n");	/* close out prompt */
			done = 1;
			break;
		}
#else
		printf("%s> ", package);
		fgets(line, sizeof(line), stdin);
		line[strlen(line)-1] = '\0';
#endif

		/* Remove leading and trailing whitespace from the line. */
		cmd = stripwhite(line);

		/* If anything left, add to history and execute it. */
		if (*cmd)
		{
#if HAVE_READLINE
			add_history(cmd);
#endif
			execute_command(cmd);
		}

#if HAVE_READLINE
		free(line);		/* realine() called malloc() */
#endif
	}
}

int main(int argc, char *argv[])
{
	jack_status_t status;

	/* basename $0 */
	package = strrchr(argv[0], '/');
	if (package == 0)
		package = argv[0];
	else
		package++;

	/* open a connection to the JACK server */
	client = jack_client_open (package, JackNullOption, &status);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		return 1;
	}

#if !WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	jack_set_process_callback(client, jack_process, 0);
	jack_on_shutdown(client, jack_shutdown, 0);

	if (jack_activate(client)) {
		fprintf(stderr, "cannot activate client");
		return 1;
	}

	/* execute commands until done */
	command_loop();

	jack_client_close(client);
	exit(0);
}
07070100000059000081A400000000000000000000000161E2F7EE00001838000000000000000000000000000000000000002000000000jack-example-tools-1/tools/tw.c/** @file tw.c
 *
 * @brief This simple client demonstrates the basic features of JACK
 * as they would be used by many applications.
 */

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;
jack_client_t *client;

/* a simple state machine for this client */
volatile enum {
	Init,
	Run,
	Exit
} client_state = Init;

static void signal_handler(int sig)
{
	jack_client_close(client);
	fprintf(stderr, "signal received, exiting ...\n");
	exit(0);
}

/**
 * The process callback for this JACK application is called in a
 * special realtime thread once for each audio cycle.
 *
 * This client follows a simple rule: when the JACK transport is
 * running, copy the input port to the output.  When it stops, exit.
 */
static int
_process (jack_nframes_t nframes)
{
	jack_default_audio_sample_t *in, *out;
	jack_transport_state_t ts = jack_transport_query(client, NULL);

	if (ts == JackTransportRolling) {

		if (client_state == Init)
			client_state = Run;

		in = jack_port_get_buffer (input_port, nframes);
		out = jack_port_get_buffer (output_port, nframes);
		memcpy (out, in,
			sizeof (jack_default_audio_sample_t) * nframes);

	} else if (ts == JackTransportStopped) {

		if (client_state == Run) {
			client_state = Exit;
			return -1;  // to stop the thread
		}
	}

	return 0;
}

static void* jack_thread(void *arg)
{
	jack_client_t* client = (jack_client_t*) arg;

	while (1) {

		jack_nframes_t frames = jack_cycle_wait (client);
		int status = _process(frames);
		jack_cycle_signal (client, status);

        /*
            Possibly do something else after signaling next clients in the graph
        */

        /* End condition */
        if (status != 0)
            return 0;
	}

    /* not reached*/
	return 0;
}

/*
static void* jack_thread(void *arg)
{
	jack_client_t* client = (jack_client_t*) arg;

	while (1) {
		jack_nframes_t frames;
		int status;
		// cycle 1
		frames = jack_cycle_wait (client);
		status = _process(frames);
		jack_cycle_signal (client, status);
		// cycle 2
		frames = jack_cycle_wait (client);
		status = _process(frames);
		jack_cycle_signal (client, status);
		// cycle 3
		frames = jack_cycle_wait (client);
		status = _process(frames);
		jack_cycle_signal (client, status);
		// cycle 4
		frames = jack_cycle_wait (client);
		status = _process(frames);
		jack_cycle_signal (client, status);
	}

	return 0;
}
*/

/**
 * JACK calls this shutdown_callback if the server ever shuts down or
 * decides to disconnect the client.
 */
static void
jack_shutdown (void *arg)
{
    fprintf(stderr, "JACK shut down, exiting ...\n");
	exit (1);
}

int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;

	if (argc >= 2) {		/* client name specified? */
		client_name = argv[1];
		if (argc >= 3) {	/* server name specified? */
			server_name = argv[2];
			options |= JackServerName;
		}
	} else {			/* use basename of argv[0] */
		client_name = strrchr(argv[0], '/');
		if (client_name == 0) {
			client_name = argv[0];
		} else {
			client_name++;
		}
	}

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/
    if (jack_set_process_thread(client, jack_thread, client) < 0)
		exit(1);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate.
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_port = jack_port_register (client, "output",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}

	if (jack_connect (client, ports[0], jack_port_name (input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
	}

	jack_free (ports);

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	jack_free (ports);

    /* install a signal handler to properly quits jack client */
    signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);

	/* keep running until the transport stops */

	while (client_state != Exit) {
		sleep (1);
	}

	jack_client_close (client);
	exit (0);
}
0707010000005A000081A400000000000000000000000161E2F7EE00000E03000000000000000000000000000000000000002200000000jack-example-tools-1/tools/wait.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>

#include <time.h>

#include <jack/jack.h>

char * my_name;

void silent_function( const char *ignore )
{
}

void
show_usage(void)
{
	fprintf(stderr, "\nUsage: %s [options]\n", my_name);
	fprintf(stderr, "Check for jack existence, or wait, until it either quits, or gets started\n");
	fprintf(stderr, "options:\n");
	fprintf(stderr, "        -s, --server <name>   Connect to the jack server named <name>\n");
	fprintf(stderr, "        -n, --name <name>     Set client name to <name>\n");
	fprintf(stderr, "        -w, --wait            Wait for server to become available\n");
	fprintf(stderr, "        -q, --quit            Wait until server is quit\n");
	fprintf(stderr, "        -c, --check           Check whether server is running\n");
	fprintf(stderr, "        -t, --timeout         Wait timeout in seconds\n");
	fprintf(stderr, "        -h, --help            Display this help message\n");
	fprintf(stderr, "For more information see http://jackaudio.org/\n");
}

int
main(int argc, char *argv[])
{
	jack_client_t *client;
	jack_status_t status;
	jack_options_t options = JackNoStartServer;
	int c;
	int option_index;
	char *server_name = NULL;
	char *client_name = NULL;
	int wait_for_start = 0;
	int wait_for_quit = 0;
	int just_check = 0;
	int wait_timeout = 0;
	time_t start_timestamp;


	struct option long_options[] = {
		{ "server", 1, 0, 's' },
		{ "wait", 0, 0, 'w' },
		{ "name", 1, 0, 'n'}, 
		{ "quit", 0, 0, 'q' },
		{ "check", 0, 0, 'c' },
		{ "timeout", 1, 0, 't' },
		{ "help", 0, 0, 'h' },
		{ 0, 0, 0, 0 }
	};

	my_name = strrchr(argv[0], '/');
	if (my_name == 0) {
		my_name = argv[0];
	} else {
		my_name ++;
	}

	while ((c = getopt_long (argc, argv, "s:n:wqct:h", long_options, &option_index)) >= 0) {
		switch (c) {
		case 's':
			server_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1));
			strcpy (server_name, optarg);
			options |= JackServerName;
			break;
		case 'n':
			client_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1));
			strcpy (client_name, optarg);
			break;
		case 'w':
			wait_for_start = 1;
			break;
		case 'q':
			wait_for_quit = 1;
			break;
		case 'c':
			just_check = 1;
			break;
		case 't':
			wait_timeout = atoi(optarg);
			break;
		case 'h':
			show_usage();
			return 1;
		default:
			show_usage();
			return 1;
		}
	}

	jack_set_info_function(silent_function);

	/* try to open server in a loop. breaking under certein conditions */

	start_timestamp = time(NULL);

	while (1) {
		if (client_name) {
			client = jack_client_open (client_name, options, &status, server_name);
		}
		else {
			client = jack_client_open ("wait", options, &status, server_name);
		}
		/* check for some real error and bail out */
		if ((client == NULL) && !(status & JackServerFailed)) {
			fprintf (stderr, "jack_client_open() failed, "
					"status = 0x%2.0x\n", status);
			return 1;
		}

		if (client == NULL) {
			if (wait_for_quit) {
				fprintf(stdout, "server is gone\n");
				break;
			}
			if (just_check) {
				fprintf(stdout, "not running\n");
				break;
			}
		} else {
			jack_client_close(client);
			if (wait_for_start) {
				fprintf(stdout, "server is available\n");
				break;
			}
			if (just_check) {
				fprintf(stdout, "running\n");
				break;
			}
		}
		if (wait_timeout) {
			if ((time(NULL) - start_timestamp) > wait_timeout) {
				fprintf(stdout, "timeout\n");
				exit(EXIT_FAILURE);
			}
		}

		// Wait a second, and repeat
#ifdef WIN32
		Sleep(1*1000);
#else
		sleep(1);
#endif
	}

	exit(0);
}
0707010000005B000041ED00000000000000000000000161E2F7EE00000000000000000000000000000000000000000000002100000000jack-example-tools-1/tools/zalsa0707010000005C000081A400000000000000000000000161E2F7EE0000894D000000000000000000000000000000000000002900000000jack-example-tools-1/tools/zalsa/LICENSE                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
0707010000005D000081A400000000000000000000000161E2F7EE0000179C000000000000000000000000000000000000002F00000000jack-example-tools-1/tools/zalsa/alsathread.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "alsathread.h"
#include "timers.h"


Alsathread::Alsathread (Alsa_pcmi *alsadev, int mode) :
    _alsadev (alsadev ),
    _mode (mode),
    _state (INIT),
    _fsize (alsadev->fsize ()),
    _audioq (0),
    _commq (0),
    _alsaq (0)
{
    // Compute DLL filter coefficients.
    _dt = (double) _fsize / _alsadev->fsamp ();
    _w1 = 2 * M_PI * 0.1 * _dt;
    _w2 = _w1 * _w1;
    _w1 *= 1.6;
}


Alsathread::~Alsathread (void)
{
    if (_state != INIT)
    {
        _state = TERM;
        thr_wait ();
    }
    else
    {
        _alsadev->pcm_stop ();
    }
}


int Alsathread::start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio)
{
    // Start the ALSA thread.
    _audioq = audioq;
    _commq = commq;
    _alsaq = alsaq;
    _state = WAIT;
    if (thr_start (SCHED_FIFO, rtprio, 0x10000)) return 1;
    return 0;
}


void Alsathread::send (int k, double t)
{
    Adata *D;

    // Send (state, frame count, timestamp) to Jack thread.
    if (_alsaq->wr_avail ())
    {
        D = _alsaq->wr_datap (); 
        D->_state = _state;
        D->_nsamp = k;
        D->_timer = t;
        _alsaq->wr_commit ();
    }
}


// The following two functions transfer data between the audio queue
// and the ALSA device. Note that we do *not* check the queue's fill
// state, and it may overrun or underrun. It actually will in the first
// few iterations and in error conditions. This is entirely intentional.
// The queue keeps correct read and write counters even in that case,
// and the  main control loop and error recovery depend on it working
// and being used in this way. 

int Alsathread::capture (void)
{
    int    c, n, k;
    float  *p;

    // Start reading from ALSA device.
    _alsadev->capt_init (_fsize);
    if (_state == PROC)
    {
	// Input frames from the ALSA device to the audio queue.
	// The outer loop takes care of wraparound.
	for (n = _fsize; n; n -= k)
	{
	    p = _audioq->wr_datap ();  // Audio queue write pointer.
	    k = _audioq->wr_linav ();  // Number of frames that can be
	    if (k > n) k = n;          // written without wraparound.
	    for (c = 0; c < _audioq->nchan (); c++)
	    {
		// Copy and interleave one channel.
		_alsadev->capt_chan (c, p + c, k, _audioq->nchan ());
	    }
	    _audioq->wr_commit (k);    // Update audio queue state.
	}
    }
    // Finish reading from ALSA device.
    _alsadev->capt_done (_fsize);
    return _fsize;
}


int Alsathread::playback (void)
{
    int    c, n, k;
    float  *p;

    // Start writing to ALSA device.
    _alsadev->play_init (_fsize);
    c = 0;
    if (_state == PROC)
    {
	// Output frames from the audio queue to the ALSA device.
	// The outer loop takes care of wraparound. 
	for (n = _fsize; n; n -= k)
	{
	    p = _audioq->rd_datap ();  // Audio queue read pointer.
	    k = _audioq->rd_linav ();  // Number of frames that can
	    if (k > n) k = n;          // be read without wraparound.
	    for (c = 0; c < _audioq->nchan (); c++)
	    {
		// De-interleave and copy one channel.
		_alsadev->play_chan (c, p + c, k, _audioq->nchan ());
	    }
	    _audioq->rd_commit (k);    // Update audio queue state.
	}
    }
    // Clear all or remaining channels.
    while (c < _alsadev->nplay ()) _alsadev->clear_chan (c++, _fsize);
    // Finish writing to ALSA device.
    _alsadev->play_done (_fsize);
    return _fsize;
}


void Alsathread::thr_main (void)
{
    int     na, nu;
    double  tw, er;

    _alsadev->pcm_start ();
    while (_state != TERM)
    {
        // Wait for next cycle, then take timestamp.
	na = _alsadev->pcm_wait ();  

	tw = tjack (jack_get_time ());
	// Check for errors - requires restart.
	if (_alsadev->state () && (na == 0))
	{
	    _state = WAIT;
	    send (0, 0);
	    usleep (10000);
	    continue;
	}
	
        // Check for commands from the Jack thread.
        if (_commq->rd_avail ())
	{
	    _state = _commq->rd_int32 ();
	    if (_state == PROC) _first = true;
	    if (_state == TERM) send (0, 0);
	}

        // We could have more than one period.
        nu = 0;
        while (na >= _fsize)
       	{
	    // Transfer frames.
	    if (_mode == PLAY) nu += playback ();
	    else               nu += capture ();
            // Update loop condition.
            na -= _fsize;
	    // Run the DLL if in PROC state.
	    if (_state == PROC)
	    {
   	        if (_first)
	        {
		    // Init DLL in first iteration.
		    _first = false;
                    _dt = (double) _fsize / _alsadev->fsamp ();
                    _t0 = tw;
	            _t1 = tw + _dt;
	        } 
	        else 
	        {
		    // Update the DLL.
		    // If we have more than one period, use
                    // the time error only for the last one.
	            if (na >= _fsize) er = 0;
                    else er = tjack_diff (tw, _t1);
	            _t0 = _t1;
	            _t1 = tjack_diff (_t1 + _dt + _w1 * er, 0.0);
	            _dt += _w2 * er;
		}
	    }
	}

	// Send number of frames used and timestamp to Jack thread.
	if (_state == PROC) send (nu, _t1);
    }
    _alsadev->pcm_stop ();
}
0707010000005E000081A400000000000000000000000161E2F7EE0000072D000000000000000000000000000000000000002E00000000jack-example-tools-1/tools/zalsa/alsathread.h// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#ifndef __ALSATHREAD_H
#define __ALSATHREAD_H


#include <zita-alsa-pcmi.h>
#include "jack/jack.h"
#include "pxthread.h"
#include "lfqueue.h"


class Alsathread : public Pxthread
{
public:

    enum { INIT, WAIT, PROC, TERM };
    enum { PLAY, CAPT };

    Alsathread (Alsa_pcmi  *alsadev, int mode);
    virtual ~Alsathread (void);
    virtual void thr_main (void);

    int start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio);

private:

    void send (int k, double t);
    int capture (void);
    int playback (void);
    
    Alsa_pcmi    *_alsadev;
    int           _mode;
    int           _state;
    int           _nfail;
    int           _fsize;
    Lfq_audio    *_audioq;
    Lfq_int32    *_commq;
    Lfq_adata    *_alsaq;
    bool          _first;
//    double        _jtmod;
    double        _t0;
    double        _t1;
    double        _dt;
    double        _w1;
    double        _w2;
};


#endif
0707010000005F000081A400000000000000000000000161E2F7EE00003572000000000000000000000000000000000000002F00000000jack-example-tools-1/tools/zalsa/jackclient.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <stdio.h>
#include <math.h>
#include "jackclient.h"
#include "alsathread.h"
#include "timers.h"


Jackclient::Jackclient (jack_client_t* cl, const char *jserv, int mode, int nchan, bool sync, void *arg) :
    _client (cl),
    _arg (arg),
    _mode (mode),
    _nchan (nchan),     
    _state (INIT),
    _freew (false),
    _resamp (0)
{
    init (jserv);
    if (!sync) _resamp = new VResampler ();
}


Jackclient::~Jackclient (void)
{
    fini ();
}


bool Jackclient::init (const char *jserv)
{
    int                 i, spol, flags;
    char                s [64];
    struct sched_param  spar;

    if (_client == 0)
    {
        fprintf (stderr, "Can't connect to Jack, is the server running ?\n");
        return false;
    }
    jack_set_process_callback (_client, jack_static_process, (void *) this);
    jack_set_latency_callback (_client, jack_static_latency, (void *) this);
    jack_set_freewheel_callback (_client, jack_static_freewheel, (void *) this);
    jack_set_buffer_size_callback (_client, jack_static_buffsize, (void *) this);
    jack_on_shutdown (_client, jack_static_shutdown, (void *) this);

    _bsize = 0;
    _fsamp = 0;
    if (jack_activate (_client))
    {
        fprintf(stderr, "Can't activate Jack");
        return false;
    }
    _jname = jack_get_client_name (_client);
    _bsize = jack_get_buffer_size (_client);
    _fsamp = jack_get_sample_rate (_client);

    flags = JackPortIsTerminal | JackPortIsPhysical;
    for (i = 0; i < _nchan; i++)
    {
	if (_mode == PLAY)
	{
            sprintf (s, "playback_%d", i + 1);
            _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE,
                                             flags | JackPortIsInput, 0);
	}
	else
	{
            sprintf (s, "capture_%d", i + 1);
            _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE,
                                             flags | JackPortIsOutput, 0);
	}
    }
    pthread_getschedparam (jack_client_thread_id (_client), &spol, &spar);
    _rprio = spar.sched_priority -  sched_get_priority_max (spol);
    _buff = new float [_bsize * _nchan];
    return true;
}


void Jackclient::fini (void)
{
    delete[] _buff;
    delete _resamp;
}


void Jackclient::jack_static_shutdown (void *arg)
{
    ((Jackclient *) arg)->sendinfo (TERM, 0, 0);
}


int Jackclient::jack_static_buffsize (jack_nframes_t nframes, void *arg)
{
    Jackclient *J = (Jackclient *) arg;

    if (J->_bsize == 0)	J->_bsize = nframes;
    else if (J->_bsize != (int) nframes) J->_state = Jackclient::TERM;
    return 0;
}


void Jackclient::jack_static_freewheel (int state, void *arg)
{
    ((Jackclient *) arg)->jack_freewheel (state);
}


void Jackclient::jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg)
{
    ((Jackclient *) arg)->jack_latency (jlcm);
}


int Jackclient::jack_static_process (jack_nframes_t nframes, void *arg)
{
    return ((Jackclient *) arg)->jack_process (nframes);
}


void Jackclient::start (Lfq_audio   *audioq,
                        Lfq_int32   *commq, 
                        Lfq_adata   *alsaq,
                        Lfq_jdata   *infoq,
                        double      ratio,
                        int         delay,
			int         ltcor,
                        int         rqual)
{
    double d;

    _audioq = audioq;
    _commq = commq;
    _alsaq = alsaq;
    _infoq = infoq;
    _ratio = ratio;
    _delay = delay;
    _rcorr = 1.0;
    if (_resamp)
    {
        _resamp->setup (_ratio, _nchan, rqual);
        _resamp->set_rrfilt (100);
        d = _resamp->inpsize () / 2.0;
        if (_mode == PLAY) d *= _ratio;
        _delay += d;
    }
    _ltcor = ltcor;
    _ppsec = (_fsamp + _bsize / 2) / _bsize;
    initwait (_ppsec / 2);
    jack_recompute_total_latencies (_client);
}


void Jackclient::initwait (int nwait)
{
    _count = -nwait;
    _commq->wr_int32 (Alsathread::WAIT);
    _state = WAIT;
    if (nwait > _ppsec) sendinfo (WAIT, 0, 0);
}


void Jackclient::initsync (void)
{
    // Reset all lock-free queues.
    _commq->reset ();
    _alsaq->reset ();
    _audioq->reset ();
    if (_resamp)
    {
        // Reset and prefill the resampler.
	_resamp->reset ();
	_resamp->inp_count = _resamp->inpsize () / 2 - 1;
	_resamp->out_count = 99999;
	_resamp->process ();
    }
    // Initialise state variables.
    _t_a0 = _t_a1 = 0;
    _k_a0 = _k_a1 = 0;
    // Initialise loop filter state.
    _z1 = _z2 = _z3 = 0;
    // Activate the ALSA thread,
    _commq->wr_int32 (Alsathread::PROC);
    _state = SYNC0;
    sendinfo (SYNC0, 0, 0);
}


void Jackclient::setloop (double bw)
{
    double w;

    // Set the loop bandwidth to bw Hz.
    w = 6.28 * bw * _bsize / _fsamp;
    _w0 = 1.0 - exp (-20.0 * w);
    _w1 = w * 2 / _bsize;
    _w2 = w / 2;
    if (_mode == PLAY) _w1 /= _ratio;
    else               _w1 *= _ratio;
}


void Jackclient::playback (int nframes)
{
    int    i, j, n;
    float  *p, *q;
    float  *inp [MAXCHAN];

    _bstat = _audioq->rd_avail ();
    for (i = 0; i < _nchan; i++)
    {
        inp [i] = (float *)(jack_port_get_buffer (_ports [i], nframes));
    }
    if (_resamp)
    {    
	// Interleave inputs into _buff.
	for (i = 0; i < _nchan; i++)
	{
	    p = inp [i];
	    q = _buff + i;
	    for (j = 0; j < _bsize; j++) q [j * _nchan] = p [j];
	}       
	// Resample _buff and write to audio queue.
	// The while loop takes care of wraparound.
	_resamp->inp_count = _bsize;
	_resamp->inp_data  = _buff;
	while (_resamp->inp_count)
	{
	    _resamp->out_count = _audioq->wr_linav ();
	    _resamp->out_data  = _audioq->wr_datap ();
	    n = _resamp->out_count;
	    _resamp->process ();
	    n -= _resamp->out_count;
	    _audioq->wr_commit (n);
	}
    }
    else
    {
        // Interleave inputs into audio queue.
	// The while loop takes care of wraparound.
	while (nframes)
	{
	    q = _audioq->wr_datap ();
	    n = _audioq->wr_linav ();
	    if (n > nframes) n = nframes;
	    for (i = 0; i < _nchan; i++)
	    {
	        p = inp [i];
	        for (j = 0; j < n; j++) q [j * _nchan] = p [j];
		inp [i] += n;
		q += 1;
	    }
	    _audioq->wr_commit (n);
	    nframes -= n;
	}
    }
}


void Jackclient::capture (int nframes)
{
    int    i, j, n;
    float  *p, *q;
    float  *out [MAXCHAN];

    for (i = 0; i < _nchan; i++)
    {
        out [i] = (float *)(jack_port_get_buffer (_ports [i], nframes));
    }
    if (_resamp)
    {
	// Read from audio queue and resample.
	// The while loop takes care of wraparound.
	_resamp->out_count = _bsize;
	_resamp->out_data  = _buff;
	while (_resamp->out_count)
	{
	    _resamp->inp_count = _audioq->rd_linav ();
	    _resamp->inp_data  = _audioq->rd_datap ();
	    n = _resamp->inp_count;
	    _resamp->process ();
	    n -= _resamp->inp_count;
	    _audioq->rd_commit (n);
	}
	// Deinterleave _buff to outputs.
	for (i = 0; i < _nchan; i++)
	{
	    p = _buff + i;
	    q = out [i];
	    for (j = 0; j < _bsize; j++) q [j] = p [j * _nchan];
	}
    }
    else
    {
        // Deinterleave audio queue to outputs.
	// The while loop takes care of wraparound.
	while (nframes)
	{
	    p = _audioq->rd_datap ();
	    n = _audioq->rd_linav ();
	    if (n > nframes) n = nframes;
	    for (i = 0; i < _nchan; i++)
	    {
	        q = out [i];
	        for (j = 0; j < n; j++) q [j] = p [j * _nchan];
		out [i] += n;
		p += 1;
	    }
	    _audioq->rd_commit (n);
	    nframes -= n;
	}
    }
    _bstat = _audioq->rd_avail ();
}


void Jackclient::silence (int nframes)
{
    int    i;
    float  *q;

    // Write silence to all jack ports.
    for (i = 0; i < _nchan; i++)
    {
        q = (float *)(jack_port_get_buffer (_ports [i], nframes));
        memset (q, 0, nframes * sizeof (float));
    }
}


void Jackclient::sendinfo (int state, double error, double ratio)
{
    Jdata *J;

    if (_infoq->wr_avail ())
    {
	J = _infoq->wr_datap ();
	J->_state = state;
	J->_error = error;
	J->_ratio = ratio;
	J->_bstat = _bstat;
	_infoq->wr_commit ();
    }
}


void Jackclient::jack_freewheel (int state)
{
    _freew = state ? true : false;
    if (_freew) initwait (_ppsec / 4);
}


void Jackclient::jack_latency (jack_latency_callback_mode_t jlcm)
{
    jack_latency_range_t R;
    int i;

    if (_state < WAIT) return;
    if (_mode == PLAY)
    {
	if (jlcm != JackPlaybackLatency) return;
	R.min = R.max = (int)(_delay / _ratio) + _ltcor;
    }
    else
    {
	if (jlcm != JackCaptureLatency) return;
	R.min = R.max = (int)(_delay * _ratio) + _ltcor;
    }
    for (i = 0; i < _nchan; i++)
    {
	jack_port_set_latency_range (_ports [i], jlcm, &R);
    }
}


int Jackclient::jack_process (int nframes)
{
    int             dk, n;
    Adata           *D;
    jack_time_t     t0, t1;
    jack_nframes_t  ft;
    float           us;
    double          tj, err, d1, d2, rd;

    // Buffer size change or other evil.
    if (_state == TERM)
    {
	sendinfo (TERM, 0, 0);
	return 0;
    }
    // Skip cylce if ports may not yet exist.
    if (_state < WAIT) return 0;

    // Start synchronisation 1/2 second after entering
    // the WAIT state. This delay allows the ALSA thread
    // to restart cleanly if necessary. Disabled while
    // freewheeling.
    if (_state == WAIT)
    {
	if (_freew) return 0;
	if (_mode == CAPT) silence (nframes);
        if (++_count == 0) initsync ();
        else return 0;
    }

    // Get the start time of the current cycle.
    jack_get_cycle_times (_client, &ft, &t0, &t1, &us);
    tj = tjack (t0);

    // Check for any skipped cycles.
    if (_state >= SYNC1)
    {
        dk = ft - _ft - _bsize;
        if (_mode == PLAY)
	{
	    dk = (int)(dk * _ratio + 0.5);
            _audioq->wr_commit (dk);
	}
	else
	{
	    dk = (int)(dk / _ratio + 0.5);    
            _audioq->rd_commit (dk);
	}
    }
    _ft = ft;
    
    // Check if we have timing data from the ALSA thread.
    n = _alsaq->rd_avail ();
    // If the data queue is full restart synchronisation.
    // This can happen e.g. on a jack engine timeout, or
    // when too many cycles have been skipped.
    if (n == _alsaq->size ())
    {
        initwait (_ppsec / 2);
        return 0;
    }
    if (n)
    {
        // Else move interval end to start, and update the
        // interval end keeping only the most recent data.
        if (_state < SYNC2) _state++;
        _t_a0 = _t_a1;
        _k_a0 = _k_a1;
        while (_alsaq->rd_avail ())
        {
            D = _alsaq->rd_datap ();
            // Restart synchronisation in case of
            // an error in the ALSA interface.
   	    if (D->_state == Alsathread::WAIT)
            {
                initwait (_ppsec / 2);
                return 0;
            }
            _t_a1 =  D->_timer;
            _k_a1 += D->_nsamp;
            _alsaq->rd_commit ();
        }
    }

    err = 0;
    if (_state >= SYNC2)
    {
        // Compute the delay error.
        d1 = tjack_diff (tj, _t_a0);
        d2 = tjack_diff (_t_a1, _t_a0);
	rd = _resamp ? _resamp->inpdist () : 0.0;

	if (_mode == PLAY)
	{
            n = _audioq->nwr () - _k_a0; // Must be done as integer as both terms will overflow.
            err = n - (_k_a1 - _k_a0) * d1 / d2  + rd * _ratio - _delay;
	}
	else
	{
            n = _k_a0 - _audioq->nrd (); // Must be done as integer as both terms will overflow.
            err = n + (_k_a1 - _k_a0) * d1 / d2  + rd - _delay ;
	}
        n = (int)(floor (err + 0.5));
        if (_state == SYNC2)
        {
            // We have the first delay error value. Adjust the audio
	    // queue to obtain the actually wanted delay, and start
	    // tracking.
	    if (_mode == PLAY) _audioq->wr_commit (-n);
	    else               _audioq->rd_commit (n);
            err -= n;
            setloop (1.0);
            _state = PROC1;
        }    
    }

    // Switch to lower bandwidth after 4 seconds.
    if ((_state == PROC1) && (++_count == 4 * _ppsec))
    {
        _state = PROC2;
        setloop (0.05);
    } 

    if (_state >= PROC1)
    {
        _z1 += _w0 * (_w1 * err - _z1);
        _z2 += _w0 * (_z1 - _z2);
        _z3 += _w2 * _z2;
        // Check error conditions.
        if (fabs (_z3) > 0.05)
        {
            // Something is really wrong, wait 10 seconds then restart.
            initwait (10 * _ppsec);
            return 0;
        }
        // Run loop filter and set resample ratio.
	if (_resamp)
	{
            _rcorr = 1 - (_z2 + _z3);
	    if (_rcorr > 1.05) _rcorr = 1.05;
	    if (_rcorr < 0.95) _rcorr = 0.95;
            _resamp->set_rratio (_rcorr);
	}
	sendinfo (_state, err, _rcorr);

	// Resample and transfer between audio
        // queue and jack ports.
	if (_mode == PLAY) playback (nframes);
	else               capture (nframes);
    }
    else if (_mode == CAPT) silence (nframes);

    return 0; 
}
07070100000060000081A400000000000000000000000161E2F7EE00000E0A000000000000000000000000000000000000002E00000000jack-example-tools-1/tools/zalsa/jackclient.h// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#ifndef __JACKCLIENT_H
#define __JACKCLIENT_H


#include <zita-resampler/vresampler.h>
#include "jack/jack.h"
#include "lfqueue.h"


class Jackclient
{
public:

    Jackclient (jack_client_t*, const char *jserv, int mode, int nchan, bool sync, void *arg);
    virtual ~Jackclient (void);
    
    enum { PLAY, CAPT, MAXCHAN = 64 };
    enum { INIT, TERM, WAIT, SYNC0, SYNC1, SYNC2, PROC1, PROC2 };

    void start (Lfq_audio   *audioq,
                Lfq_int32   *commq, 
	        Lfq_adata   *alsaq,
		Lfq_jdata   *infoq,
                double      ratio,
	        int         delay,
	        int         ltcor,
	        int         rqual);

    const char *jname (void) const { return _jname; }
    int fsamp (void) const { return _fsamp; }
    int bsize (void) const { return _bsize; }
    int rprio (void) const { return _rprio; }
    void *getarg(void) const { return _arg; }

private:

    bool init (const char *jserv);
    void fini (void);
    void initwait (int nwait);
    void initsync (void);
    void setloop (double bw);
    void silence (int nframes);
    void playback (int nframes);
    void capture (int nframes);
    void sendinfo (int state, double error, double ratio);

    virtual void thr_main (void) {}

    void jack_freewheel (int state);
    void jack_latency (jack_latency_callback_mode_t jlcm);
    int  jack_process (int nframes);

    jack_client_t  *_client;
    jack_port_t    *_ports [MAXCHAN];
    void           *_arg;
    const char     *_jname;
    int             _mode;
    int             _nchan;
    int             _state;
    int             _count;
    int             _fsamp;
    int             _bsize;
    int             _rprio;
    bool            _freew;
    float          *_buff;
 
    Lfq_audio      *_audioq;
    Lfq_int32      *_commq; 
    Lfq_adata      *_alsaq;
    Lfq_jdata      *_infoq;
    double          _ratio;
    int             _ppsec;
    int             _bstat;

    jack_nframes_t  _ft;
    double          _t_a0;
    double          _t_a1;
    int             _k_a0;
    int             _k_a1;
    double          _delay;
    int             _ltcor;

    double           _w0;
    double           _w1;
    double           _w2;
    double           _z1;
    double           _z2;
    double           _z3;
    double          _rcorr;
    VResampler     *_resamp;

    static void jack_static_shutdown (void *arg);
    static int  jack_static_buffsize (jack_nframes_t nframes, void *arg);
    static void jack_static_freewheel (int state, void *arg);
    static void jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg);
    static int  jack_static_process (jack_nframes_t nframes, void *arg);
};


#endif
07070100000061000081A400000000000000000000000161E2F7EE00000750000000000000000000000000000000000000002C00000000jack-example-tools-1/tools/zalsa/lfqueue.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <assert.h>
#include "lfqueue.h"


Lfq_adata::Lfq_adata (int size) :
    _size (size),
    _mask (size - 1),
    _nwr (0),
    _nrd (0)
{
    assert (!(_size & _mask));
    _data = new Adata [_size];
}

Lfq_adata::~Lfq_adata (void)
{
    delete[] _data;
} 


Lfq_jdata::Lfq_jdata (int size) :
    _size (size),
    _mask (size - 1),
    _nwr (0),
    _nrd (0)
{
    assert (!(_size & _mask));
    _data = new Jdata [_size];
}

Lfq_jdata::~Lfq_jdata (void)
{
    delete[] _data;
} 


Lfq_int32::Lfq_int32 (int size) :
    _size (size),
    _mask (size - 1),
    _nwr (0),
    _nrd (0)
{
    assert (!(_size & _mask));
    _data = new int32_t [_size];
}

Lfq_int32::~Lfq_int32 (void)
{
    delete[] _data;
} 


Lfq_audio::Lfq_audio (int nsamp, int nchan) :
    _size (nsamp),
    _mask (nsamp - 1),
    _nch (nchan),
    _nwr (0),
    _nrd (0)
{
    assert (!(_size & _mask));
    _data = new float [_nch * _size];
}

Lfq_audio::~Lfq_audio (void)
{
    delete[] _data;
} 


07070100000062000081A400000000000000000000000161E2F7EE000011AE000000000000000000000000000000000000002B00000000jack-example-tools-1/tools/zalsa/lfqueue.h// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#ifndef __LFQUEUE_H
#define __LFQUEUE_H


#include <stdint.h>
#include <string.h>


class Adata
{
public:

    int32_t  _state;
    int32_t  _nsamp;
    double   _timer;
};


class Lfq_adata
{
public:

    Lfq_adata (int size);
    ~Lfq_adata (void); 

    void reset (void) { _nwr = _nrd = 0; }
    int  size (void) const { return _size; }

    int       wr_avail (void) const { return _size - _nwr + _nrd; } 
    Adata    *wr_datap (void) { return _data + (_nwr & _mask); }
    void      wr_commit (void) { _nwr++; }

    int       rd_avail (void) const { return _nwr - _nrd; } 
    Adata    *rd_datap (void) { return _data + (_nrd & _mask); }
    void      rd_commit (void) { _nrd++; }

private:

    Adata    *_data;
    int       _size;
    int       _mask;
    int       _nwr;
    int       _nrd;
};


class Jdata
{
public:

    int32_t  _state;
    double   _error;
    double   _ratio;
    int      _bstat;
};


class Lfq_jdata
{
public:

    Lfq_jdata (int size);
    ~Lfq_jdata (void); 

    void reset (void) { _nwr = _nrd = 0; }
    int  size (void) const { return _size; }

    int       wr_avail (void) const { return _size - _nwr + _nrd; } 
    Jdata    *wr_datap (void) { return _data + (_nwr & _mask); }
    void      wr_commit (void) { _nwr++; }

    int       rd_avail (void) const { return _nwr - _nrd; } 
    Jdata    *rd_datap (void) { return _data + (_nrd & _mask); }
    void      rd_commit (void) { _nrd++; }

private:

    Jdata    *_data;
    int       _size;
    int       _mask;
    int       _nwr;
    int       _nrd;
};


class Lfq_int32
{
public:

    Lfq_int32 (int size);
    ~Lfq_int32 (void); 

    int  size (void) const { return _size; }
    void reset (void) { _nwr = _nrd = 0; }

    int      wr_avail (void) const { return _size - _nwr + _nrd; } 
    int32_t *wr_datap (void) { return _data + (_nwr & _mask); }
    void     wr_commit (void) { _nwr++; }

    int      rd_avail (void) const { return _nwr - _nrd; } 
    int32_t *rd_datap (void) { return _data + (_nrd & _mask); }
    void     rd_commit (void) { _nrd++; }

    void     wr_int32 (int32_t v) { _data [_nwr++ & _mask] = v; }
    void     wr_uint32 (uint32_t v) { _data [_nwr++ & _mask] = v; }
    void     wr_float (float v) { *(float *)(_data + (_nwr++ & _mask)) = v; }

    int32_t  rd_int32 (void) { return  _data [_nrd++ & _mask]; }
    int32_t  rd_uint32 (void) { return _data [_nrd++ & _mask]; }
    float    rd_float (void) { return *(float *)(_data + (_nrd++ & _mask)); }

private:

    int32_t  *_data;
    int       _size;
    int       _mask;
    int       _nwr;
    int       _nrd;
};


class Lfq_audio
{
public:

    Lfq_audio (int nsamp, int nchan);
    ~Lfq_audio (void); 

    int  size (void) const { return _size; }
    void reset (void)
    {
        _nwr = _nrd = 0;
	memset (_data, 0, _size * _nch * sizeof (float));
    }

    int     nchan (void) const { return _nch; } 
    int     nwr (void) const { return _nwr; };
    int     nrd (void) const { return _nrd; };

    int     wr_avail (void) const { return _size - _nwr + _nrd; } 
    int     wr_linav (void) const { return _size - (_nwr & _mask); }
    float  *wr_datap (void) { return _data + _nch * (_nwr & _mask); }
    void    wr_commit (int k) { _nwr += k; }

    int     rd_avail (void) const { return _nwr - _nrd; } 
    int     rd_linav (void) const { return _size - (_nrd & _mask); }
    float  *rd_datap (void) { return _data + _nch * (_nrd & _mask); }
    void    rd_commit (int k) { _nrd += k; }

private:

    float    *_data;
    int       _size;
    int       _mask;
    int       _nch;
    int       _nwr;
    int       _nrd;
};


#endif

07070100000063000081A400000000000000000000000161E2F7EE000003C0000000000000000000000000000000000000002D00000000jack-example-tools-1/tools/zalsa/meson.build
zalsa_version = '0.8.4'

zalsa_in_c_args = c_args_common + ['-DAPPNAME="zalsa_in"', '-DVERSION="@0@"'.format(zalsa_version)]
lib_zalsa_in = library(
  'zalsa_in',
  cpp_args: zalsa_in_c_args,
  name_prefix: '',
  sources: ['zita-a2j.cc', 'alsathread.cc', 'jackclient.cc', 'pxthread.cc', 'lfqueue.cc'],
  dependencies: [dep_alsa, dep_jack, dep_threads, lib_jackserver, lib_m, lib_rt, lib_zita_alsa_pcmi, lib_zita_resampler],
  install: true,
  install_dir: get_option('libdir') / 'jack',
)

zalsa_out_c_args = c_args_common + ['-DAPPNAME="zalsa_out"', '-DVERSION="@0@"'.format(zalsa_version)]
lib_zalsa_out = library(
  'zalsa_out',
  cpp_args: zalsa_out_c_args,
  name_prefix: '',
  sources: ['zita-j2a.cc', 'alsathread.cc', 'jackclient.cc', 'pxthread.cc', 'lfqueue.cc'],
  dependencies: [dep_alsa, dep_jack, dep_threads, lib_jackserver, lib_m, lib_rt, lib_zita_alsa_pcmi, lib_zita_resampler],
  install: true,
  install_dir: get_option('libdir') / 'jack',
)
07070100000064000081A400000000000000000000000161E2F7EE00000893000000000000000000000000000000000000002D00000000jack-example-tools-1/tools/zalsa/pxthread.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include "pxthread.h"


Pxthread::Pxthread (void) :  _thrid (0)
{
}


Pxthread::~Pxthread (void)
{
}


extern "C" void *Pxthread_entry_point (void *arg)
{
    Pxthread *T = (Pxthread *) arg;
    T->thr_main ();
    return NULL;
}


int Pxthread::thr_start (int policy, int priority, size_t stacksize)
{
    int                min, max, rc;
    pthread_attr_t     attr;
    struct sched_param parm;

    min = sched_get_priority_min (policy);
    max = sched_get_priority_max (policy);
    priority += max;
    if (priority > max) priority = max;
    if (priority < min) priority = min;
    parm.sched_priority = priority;

    pthread_attr_init (&attr);
    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
    pthread_attr_setschedpolicy (&attr, policy);
    pthread_attr_setschedparam (&attr, &parm);
    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setstacksize (&attr, stacksize);

    _thrid = 0; 
    rc = pthread_create (&_thrid,
			 &attr,
			 Pxthread_entry_point,
			 this);

    pthread_attr_destroy (&attr);

    return rc;
}


void Pxthread::thr_main (void)
{
}


void Pxthread::thr_wait (void)
{
    if (_thrid == 0)
        return;
    pthread_join (_thrid, NULL);
    _thrid = 0;
}

07070100000065000081A400000000000000000000000161E2F7EE00000595000000000000000000000000000000000000002C00000000jack-example-tools-1/tools/zalsa/pxthread.h// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#ifndef __PXTHREAD_H
#define __PXTHREAD_H


#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>


class Pxthread
{
public:

    Pxthread (void);
    virtual ~Pxthread (void);
    Pxthread (const Pxthread&);
    Pxthread& operator=(const Pxthread&);

    virtual void thr_main (void) = 0;
    virtual int  thr_start (int policy, int priority, size_t stacksize = 0);
    virtual void thr_wait (void);

private:
  
    pthread_t  _thrid;
};


#endif
07070100000066000081A400000000000000000000000161E2F7EE0000054B000000000000000000000000000000000000002A00000000jack-example-tools-1/tools/zalsa/timers.h// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#ifndef __TIMERS_H
#define __TIMERS_H


#include <math.h>
#include <sys/time.h>
#include <jack/jack.h>


#define tjack_mod ldexp (1e-6f, 32)



inline double tjack_diff (double a, double b)    
{
    double d, m;

    d = a - b;
    m = tjack_mod;
    while (d < -m / 2) d += m;
    while (d >= m / 2) d -= m;
    return d;
}


inline double tjack (jack_time_t t, double dt = 0)
{
    int32_t u = (int32_t)(t & 0xFFFFFFFFLL);
    return 1e-6 * u;
}


#endif
07070100000067000081A400000000000000000000000161E2F7EE00002CF0000000000000000000000000000000000000002D00000000jack-example-tools-1/tools/zalsa/zita-a2j.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <signal.h>
#include "alsathread.h"
#include "jackclient.h"
#include "lfqueue.h"
#include "jack/control.h"

static const char *clopt = "hvLSwj:d:r:p:n:c:Q:I:";

static void help (void)
{
    jack_info ("%s-%s", APPNAME, VERSION);
    jack_info ("(C) 2012-2018 Fons Adriaensen  <fons@linuxaudio.org>");
    jack_info ("Use ALSA capture device as a Jack client.");
    jack_info ("Options:");
    jack_info ("  -h                 Display this text");
    jack_info ("  -j <jackname>      Name as Jack client [%s]", APPNAME);
    jack_info ("  -d <device>        ALSA capture device [none]");
    jack_info ("  -r <rate>          Sample rate [48000]");
    jack_info ("  -p <period>        Period size [256]");
    jack_info ("  -n <nfrags>        Number of fragments [2]");
    jack_info ("  -c <nchannels>     Number of channels [2]");
    jack_info ("  -S                 Word clock sync, no resampling");
    jack_info ("  -Q <quality>       Resampling quality, 16..96 [auto]");
    jack_info ("  -I <samples>       Latency adjustment [0]");
    jack_info ("  -L                 Force 16-bit and 2 channels [off]");
    jack_info ("  -w                 Wait until soundcard is available [off]");
    jack_info ("  -v                 Print tracing information [off]");
}

class zita_a2j
{
	Lfq_int32 *commq;
	Lfq_adata *alsaq;
	Lfq_jdata *infoq;
	Lfq_audio *audioq;
	bool stop;
	bool v_opt;
	bool L_opt;
	bool S_opt;
	bool w_opt;
	char *jname;
	char *device;
	int fsamp;
	int bsize;
	int nfrag;
	int nchan;
	int rqual;
	int ltcor;

public:

    zita_a2j()
    {
        commq = new Lfq_int32(16);
        alsaq = new Lfq_adata(256);
        infoq = new Lfq_jdata(256);
        audioq = 0;
        stop = false;
        v_opt = false;
        L_opt = false;
        S_opt = false;
        w_opt = false;
        jname = strdup(APPNAME);
        device = 0;
        fsamp = 48000;
        bsize = 128;
        nfrag = 2;
        nchan = 2;
        rqual = 0;
        ltcor = 0;
        A = 0;
        C = 0;
        J = 0;
        t = 0;
    }

private:

    int procoptions (int ac, const char *av [])
    {
        int k;
        
        optind = 1;
        opterr = 0;
        while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1)
        {
            if (optarg && (*optarg == '-'))
            {
                jack_error (APPNAME ":   Missing argument for '-%c' option.", k);
                jack_error (APPNAME ":   Use '-h' to see all options.");
                return 1;
            }
            switch (k)
            {
            case 'h' : help (); return 1;
            case 'v' : v_opt = true; break;
            case 'L' : L_opt = true; break;
            case 'S' : S_opt = true; break;
            case 'w' : w_opt = true; break;
            case 'j' : jname = optarg; break;
            case 'd' : device = optarg; break;
            case 'r' : fsamp = atoi (optarg); break;    
            case 'p' : bsize = atoi (optarg); break;    
            case 'n' : nfrag = atoi (optarg); break;    
            case 'c' : nchan = atoi (optarg); break;    
            case 'Q' : rqual = atoi (optarg); break;    
            case 'I' : ltcor = atoi (optarg); break;    
            case '?':
                if (optopt != ':' && strchr (clopt, optopt))
                {
                    jack_error (APPNAME ":   Missing argument for '-%c' option.", optopt);
                }
                else if (isprint (optopt))
                {
                    jack_error (APPNAME ":   Unknown option '-%c'.", optopt);
                }
                else
                {
                    jack_error (APPNAME ":   Unknown option character '0x%02x'.", optopt & 255);
                }
                jack_error (APPNAME ":   Use '-h' to see all options.");
                return 1;
            default:
                return 1;
            }
        }
        return 0;
    }

    int parse_options (const char* load_init)
    {
        int argsz;
        int argc = 0;
        const char** argv;
        char* args = strdup (load_init);
        char* token;
        char* ptr = args;
        char* savep;

	    if (!load_init) {
            return 0;
        }

        argsz = 8; /* random guess at "maxargs" */
        argv = (const char **) malloc (sizeof (char *) * argsz);

        argv[argc++] = APPNAME;

        while (1) {

            if ((token = strtok_r (ptr, " ", &savep)) == NULL) {
                break;
            }

            if (argc == argsz) {
                argsz *= 2;
                argv = (const char **) realloc (argv, sizeof (char *) * argsz);
            }

            argv[argc++] = token;
            ptr = NULL;
        }

        return procoptions (argc, argv);
    }

    void printinfo (void)
    {
        int     n, k;
        double  e, r;
        Jdata   *J;

        n = 0;
        k = 99999;
        e = r = 0;
        while (infoq->rd_avail ())
        {
            J = infoq->rd_datap ();
            if (J->_state == Jackclient::TERM)
            {
                jack_error (APPNAME ": Fatal error condition, terminating.");
                stop = true;
                return;
            }
            else if (J->_state == Jackclient::WAIT)
            {
                jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds.");
                n = 0;
            }
            else if (J->_state == Jackclient::SYNC0)
            {
                jack_info (APPNAME ": Starting synchronisation.");
            }
            else if (v_opt)
            {
                n++;
                e += J->_error;
                r += J->_ratio;
                if (J->_bstat < k) k = J->_bstat;
            }
            infoq->rd_commit ();
        }
        if (n) jack_info (APPNAME ": %8.3lf %10.6lf %5d", e / n, r / n, k);
    }


    Alsa_pcmi      *A;
    Alsathread     *C;
    Jackclient     *J;

    pthread_t t;
    int       topts;

    static void* _retry_alsa_pcmi (void *arg)
    {
        ((zita_a2j*)arg)->retry_alsa_pcmi ();
        return NULL;
    }

    void retry_alsa_pcmi ()
    {
        Alsa_pcmi *a;

        while (! stop)
        {
            sleep(1);

            a = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, topts);
            if (a->state ())
            {
                delete a;
                continue;
            }

            A = a;
            if (v_opt) A->printinfo ();
            C = new Alsathread (A, Alsathread::CAPT);
            usleep (100*1000);
            jack_initialize_part2 ();
            jack_info (APPNAME ": Device is now available and has been activated");
            break;
        }

        t = 0;
    }

public:

    int
    jack_initialize (jack_client_t* client, const char* load_init)
    {
        int opts;

        if (parse_options (load_init)) {
            jack_error (APPNAME ": parse options failed");
            delete this;
            return 1;
        }

        if (device == 0)
        {
            help ();
            delete this;
            return 1;
        }
        if (rqual < 16) rqual = 16;
        if (rqual > 96) rqual = 96;
        if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1))
        {
            jack_error (APPNAME ": Illegal parameter value(s).");
            delete this;
            return 1;
        }

        opts = 0;
        if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL;
        if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH;
        if (w_opt)
        {
            J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this);
            A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts);

            // if device is not available, spawn thread to keep trying
            if (A->state ())
            {
                delete A;
                A = NULL;
                topts = opts;
                pthread_create (&t, NULL, _retry_alsa_pcmi, this);
                jack_info (APPNAME ": Could not open device, will keep trying in new thread...");
                return 0;
            }

            // otherwise continue as normal
            if (v_opt) A->printinfo ();
            C = new Alsathread (A, Alsathread::CAPT);
        }
        else
        {
            A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts);
            if (A->state ())
            {
                jack_error (APPNAME ": Can't open ALSA capture device '%s'.", device);
                delete this;
                return 1;
            }
            if (v_opt) A->printinfo ();
            if (nchan > A->ncapt ())
            {
                nchan = A->ncapt ();
                jack_error (APPNAME ": Warning: only %d channels are available.", nchan);
            }
            C = new Alsathread (A, Alsathread::CAPT);
            J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this);
        }

        usleep (100*1000);
        jack_initialize_part2 ();
        return 0;
    }

    void jack_initialize_part2 ()
    {
        int            k, k_del;
        double         t_alsa;
        double         t_jack;
        double         t_del;

        t_alsa = (double) bsize / fsamp;
        if (t_alsa < 1e-3) t_alsa = 1e-3;
        t_jack = (double) J->bsize () / J->fsamp (); 
        t_del = t_alsa + t_jack;
        k_del = (int)(t_del * fsamp);
        for (k = 256; k < 2 * k_del; k *= 2);
        audioq = new Lfq_audio (k, nchan);

        if (rqual == 0)
        {
            k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp ();
            if (k < 44100) k = 44100;
            rqual = (int)((6.7 * k) / (k - 38000));
        }
        if (rqual < 16) rqual = 16;
        if (rqual > 96) rqual = 96;

        C->start (audioq, commq, alsaq, J->rprio () + 10);
        J->start (audioq, commq, alsaq, infoq, J->fsamp () / (double) fsamp, k_del, ltcor, rqual);
    }

    void jack_finish (void* arg)
    {
        if (t != 0)
        {
            stop = true;
            pthread_join(t, NULL);
        }

        commq->wr_int32 (Alsathread::TERM);
        usleep (100000);
        delete C;
        delete A;
        delete J;
        delete audioq;
    }
};

extern "C" {

int
jack_initialize (jack_client_t* client, const char* load_init)
{
	zita_a2j *c = new zita_a2j();
	return c->jack_initialize(client, load_init);
}

void jack_finish (void* arg)
{
	if (!arg) return;
	Jackclient *J = (Jackclient *)arg;
	zita_a2j *c = (zita_a2j *)J->getarg();
	c->jack_finish(arg);
	delete c;
}

} /* extern "C" */
07070100000068000081A400000000000000000000000161E2F7EE00002CBA000000000000000000000000000000000000002D00000000jack-example-tools-1/tools/zalsa/zita-j2a.cc// ----------------------------------------------------------------------------
//
//  Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
//    
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------


#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <signal.h>
#include "alsathread.h"
#include "jackclient.h"
#include "lfqueue.h"
#include "jack/control.h"

static const char *clopt = "hvLSwj:d:r:p:n:c:Q:O:";

static void help (void)
{
    jack_info ("%s-%s", APPNAME, VERSION);
    jack_info ("(C) 2012-2018 Fons Adriaensen  <fons@linuxaudio.org>");
    jack_info ("Use ALSA playback device as a Jack client.");
    jack_info ("Options:");
    jack_info ("  -h                 Display this text");
    jack_info ("  -j <jackname>      Name as Jack client [%s]", APPNAME);
    jack_info ("  -d <device>        ALSA playback device [none]");
    jack_info ("  -r <rate>          Sample rate [48000]");
    jack_info ("  -p <period>        Period size [256]");
    jack_info ("  -n <nfrags>        Number of fragments [2]");
    jack_info ("  -c <nchannels>     Number of channels [2]");
    jack_info ("  -S                 Word clock sync, no resampling");
    jack_info ("  -Q <quality>       Resampling quality, 16..96 [auto]");
    jack_info ("  -O <samples>       Latency adjustment [0]");
    jack_info ("  -L                 Force 16-bit and 2 channels [off]");
    jack_info ("  -w                 Wait until soundcard is available [off]");
    jack_info ("  -v                 Print tracing information [off]");
}

class zita_j2a
{
	Lfq_int32 *commq;
	Lfq_adata *alsaq;
	Lfq_jdata *infoq;
	Lfq_audio *audioq;
	bool stop;
	bool v_opt;
	bool L_opt;
	bool S_opt;
	bool w_opt;
	char *jname;
	char *device;
	int fsamp;
	int bsize;
	int nfrag;
	int nchan;
	int rqual;
	int ltcor;

public:

    zita_j2a()
    {
        commq = new Lfq_int32(16);
        alsaq = new Lfq_adata(256);
        infoq = new Lfq_jdata(256);
        audioq = 0;
        stop = false;
        v_opt = false;
        L_opt = false;
        S_opt = false;
        w_opt = false;
        jname = strdup(APPNAME);
        device = 0;
        fsamp = 48000;
        bsize = 128;
        nfrag = 2;
        nchan = 2;
        rqual = 0;
        ltcor = 0;
        A = 0;
        P = 0;
        J = 0;
        t = 0;
    }

private:

    int procoptions (int ac, const char *av [])
    {
        int k;

        optind = 1;
        opterr = 0;
        while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1)
        {
            if (optarg && (*optarg == '-'))
            {
                jack_error (APPNAME ":   Missing argument for '-%c' option.", k);
                jack_error (APPNAME ":   Use '-h' to see all options.");
                return 1;
            }
            switch (k)
            {
            case 'h' : help (); return 1;
            case 'v' : v_opt = true; break;
            case 'L' : L_opt = true; break;
            case 'S' : S_opt = true; break;
            case 'w' : w_opt = true; break;
            case 'j' : jname = optarg; break;
            case 'd' : device = optarg; break;
            case 'r' : fsamp = atoi (optarg); break;    
            case 'p' : bsize = atoi (optarg); break;    
            case 'n' : nfrag = atoi (optarg); break;    
            case 'c' : nchan = atoi (optarg); break;    
            case 'Q' : rqual = atoi (optarg); break;    
            case 'O' : ltcor = atoi (optarg); break;    
            case '?':
                if (optopt != ':' && strchr (clopt, optopt))
                {
                    jack_error (APPNAME ":   Missing argument for '-%c' option.", optopt); 
                }
                else if (isprint (optopt))
                {
                    jack_error (APPNAME ":   Unknown option '-%c'.", optopt);
                }
                else
                {
                    jack_error (APPNAME ":   Unknown option character '0x%02x'.", optopt & 255);
                }
                jack_error (APPNAME ":   Use '-h' to see all options.");
                return 1;
            default:
                return 1;
            }
        }

        return 0;
    }

    int parse_options (const char* load_init)
    {
        int argsz;
        int argc = 0;
        const char** argv;
        char* args = strdup (load_init);
        char* token;
        char* ptr = args;
        char* savep;

        if (!load_init) {
            return 0;
        }

        argsz = 8; /* random guess at "maxargs" */
        argv = (const char **) malloc (sizeof (char *) * argsz);

        argv[argc++] = APPNAME;

        while (1) {

            if ((token = strtok_r (ptr, " ", &savep)) == NULL) {
                break;
            }

            if (argc == argsz) {
                argsz *= 2;
                argv = (const char **) realloc (argv, sizeof (char *) * argsz);
            }

            argv[argc++] = token;
            ptr = NULL;
        }

        return procoptions (argc, argv);
    }

    void printinfo (void)
    {
        int     n, k;
        double  e, r;
        Jdata   *J;

        n = 0;
        k = 99999;
        e = r = 0;
        while (infoq->rd_avail ())
        {
            J = infoq->rd_datap ();
            if (J->_state == Jackclient::TERM)
            {
                jack_info (APPNAME ": Fatal error condition, terminating.");
                stop = true;
                return;
            }
            else if (J->_state == Jackclient::WAIT)
            {
                jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds.");
                n = 0;
            }
            else if (J->_state == Jackclient::SYNC0)
            {
                jack_info (APPNAME ": Starting synchronisation.");
            }
            else if (v_opt)
            {
                n++;
                e += J->_error;
                r += J->_ratio;
                if (J->_bstat < k) k = J->_bstat;
            }
            infoq->rd_commit ();
        }
        if (n) jack_info ("%8.3lf %10.6lf %5d", e / n, r / n, k);
    }

    Alsa_pcmi      *A;
    Alsathread     *P;
    Jackclient     *J;

    pthread_t t;
    int       topts;

    static void* _retry_alsa_pcmi (void *arg)
    {
        ((zita_j2a*)arg)->retry_alsa_pcmi ();
        return NULL;
    }

    void retry_alsa_pcmi ()
    {
        Alsa_pcmi *a;

        while (! stop)
        {
            sleep(1);

            a = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, topts);
            if (a->state ())
            {
                delete a;
                continue;
            }

            A = a;
            if (v_opt) A->printinfo ();
            P = new Alsathread (A, Alsathread::PLAY);
            usleep (100*1000);
            jack_initialize_part2 ();
            jack_info (APPNAME ": Device is now available and has been activated");
            break;
        }

        t = 0;
    }

public:

    int jack_initialize (jack_client_t* client, const char* load_init)
    {
        int opts;

        if (parse_options (load_init)) {
            delete this;
            return 1;
        }

        if (device == 0)
        {
            help ();
            delete this;
            return 1;
        }
        if (rqual < 16) rqual = 16;
        if (rqual > 96) rqual = 96;
        if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1))
        {
            jack_error (APPNAME ": Illegal parameter value(s).");
            delete this;
            return 1;
        }

        opts = 0;
        if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL;
        if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH;
        if (w_opt)
        {
            J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this);

            // if device is not available, spawn thread to keep trying
            A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts);
            if (A->state ())
            {
                delete A;
                A = NULL;
                topts = opts;
                pthread_create (&t, NULL, _retry_alsa_pcmi, this);
                jack_info (APPNAME ": Could not open device, will keep trying in new thread...");
                return 0;
            }

            // otherwise continue as normal
            if (v_opt) A->printinfo ();
            P = new Alsathread (A, Alsathread::PLAY);
        }
        else
        {
            A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts);
            if (A->state ())
            {
                jack_error (APPNAME ": Can't open ALSA playback device '%s'.", device);
                delete this;
                return 1;
            }
            if (v_opt) A->printinfo ();
            if (nchan > A->nplay ())
            {
                nchan = A->nplay ();
                jack_error (APPNAME ": Warning: only %d channels are available.", nchan);
            }
            P = new Alsathread (A, Alsathread::PLAY);
            J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this);
        }

        usleep (100*1000);
        jack_initialize_part2 ();
        return 0;
    }

    void jack_initialize_part2 ()
    {
        int            k, k_del;
        double         t_jack;
        double         t_alsa;
        double         t_del;

        t_alsa = (double) bsize / fsamp;
        if (t_alsa < 1e-3) t_alsa = 1e-3;
        t_jack = (double) J->bsize () / J->fsamp (); 
        t_del = t_alsa + t_jack;
        k_del = (int)(t_del * fsamp);
        for (k = 256; k < 2 * k_del; k *= 2);
        audioq = new Lfq_audio (k, nchan);

        if (rqual == 0)
        {
            k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp ();
            if (k < 44100) k = 44100;
            rqual = (int)((6.7 * k) / (k - 38000));
        }
        if (rqual < 16) rqual = 16;
        if (rqual > 96) rqual = 96;

        P->start (audioq, commq, alsaq, J->rprio () + 10);
        J->start (audioq, commq, alsaq, infoq, (double) fsamp / J->fsamp (), k_del, ltcor, rqual);
    }

    void jack_finish (void* arg)
    {
        if (t != 0)
        {
            stop = true;
            pthread_join(t, NULL);
            t = 0;
        }

        commq->wr_int32 (Alsathread::TERM);
        usleep (100*1000);
        delete P;
        delete A;
        delete J;
        delete audioq;
    }
};

extern "C" {

int
jack_initialize (jack_client_t* client, const char* load_init)
{
	zita_j2a *c = new zita_j2a();
	return c->jack_initialize(client, load_init);
}

void jack_finish (void* arg)
{
	if (!arg) return;
	Jackclient *J = (Jackclient *)arg;
	zita_j2a *c = (zita_j2a *)J->getarg();
	c->jack_finish(arg);
	delete c;
}

} /* extern "C" */
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!1128 blocks
openSUSE Build Service is sponsored by