Attached are two patches:
* The logs patch replaces various calls to fprintf(),printf() and
fputs() with calls to jack_error() and newly appeared jack_info()
functionality. It also fixes some obvious error/info log mismatches
in current code.
* The dbus patch provides additional fronted to jack server, alternative
to jackd. the dbus object is auto activatated when
needed. Starting and stopping of the jack server are methods of the
dbus object. Other methods are for setting/getting jack
settings. Settings are being persisted.
D-Bus patch requires logs patch. As currently exported it also requires
midi-alsa-munge patch, but this is not real requirement.
So patch apply order is (against latest svn, tested with r1070):
* jackd-midi-alsa-munge-r1051.patch (p0)
* jack-logs-20071209-r1070.patch (p1)
* jack-dbus-20071209-r1070.patch (p1)
What is not implemented yet:
* Provide access to clock source parameter (tricky)
* Provide access to debug-timer parameter (not fully documented -
optarg)
* Send signals to (control) apps (status changes, connections, clients,
port renames, xruns, error and info logs)
* In client library, when compiled with dbus support, try to start via
dbus frontend first (auto-activation)
* Implement configurator supporting multiple user configurations
(separate D-Bus object)
D-Bus patch currently requires dbus-glib for main code and libxml2 for
settings persistence. Applying patch enables configure time checks for
required libraries and if they are not present, corresponding feature is
not built.
Currently there is problem with ffado driver (freebob works). libffado
uses libxml++ that uses libxml2. libxml2 has quite lot of global
things, Including global hooks used by libxml++ and initialized in
constructor global object. To avoid crashes when ffado driver is
available, it is ignored by the jackdbus frontend (it is still available
in jackd). This is temporary solution. I could of course don't use
libxml2 but this will only delay effect in ffado driver until some other
driver is starts using libxml2.
After compiling and installing jackdbus, you will get also a small
python app, jack_control that allows accessing of jackdbus. jack_control
is test app, and while quite usable is not supposed to be in line with
full-featured jack control apps like qjackctl and patchage.
Theory of operation:
JACK server works in background with log file and settings preserved in
~/.jackdbus/ directory. jack controller dbus object is autoactivated
when accessed. Thus jack server works in background while allowing to
access it post factum, either logs, settings or start/stop.
Multiconfig functionality is provided by separate object to be reused by
control apps like patchage and qjackctl. All of them will reuse jack
presets and user will get transparent workflow.
If they adapt it. Dave, Rui?
--
Nedko Arnaudov <GnuPG KeyID: DE1716B0>
hello,
I am trying to develop an app using jack. My first goal is to play a
stereo wav.
I've used clockloop http://plugin.org.uk/clockloop by Steve Harris as a
starting point. It uses libsndfile to open a mono wav.
I've reached a point where 2 outputs are created and connected to the
first two outputs of the sound card.
I managed to send a mono file to both outs. I've opened a stereo file,
but I'm having trouble outputting it correctly.
I am a bit confused on how to continue.
If someone could give me some pointers would be much appreciated.
thanks in advance
stefanos
This is what I have so far:
//================ audio.c ===============
/*
* Copyright (C) 2003 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.
*/
#include <stdlib.h>
#include <jack/jack.h>
#include "audio.h"
#include <stdio.h>
buffer_t *buffers = NULL;
unsigned int buffer_size = 0;
unsigned int num_buffers = 0;
unsigned int play_pos = 0;
float gain_inc = 0.01f;
float c_gain = 0.1f;
jack_client_t *client;
jack_port_t *output_port_ML;
jack_port_t *output_port_MR;
int process(jack_nframes_t nframes, void *arg)
{
unsigned int i,j;
sample_t *outML = (sample_t *)jack_port_get_buffer(output_port_ML,
nframes);
sample_t *outMR = (sample_t *)jack_port_get_buffer(output_port_MR,
nframes);
for (j=0; j<nframes; j++) {
outML[j] = 0.0f;
outMR[j] = 0.0f;
}
for (i=0; i<num_buffers; i=i++) {
if (buffers[i].state == on) {
for (j=0; j<nframes; j++) {
outML[j] += (buffers[i].data[(play_pos + j) %
buffer_size]) * c_gain;
outMR[j] += (buffers[i].data[(play_pos + j) %
buffer_size]) * c_gain;
}
}
}
play_pos = (play_pos + nframes) % buffer_size;
return 0;
}
//====================== audio.h ======================
#ifndef AUDIO_H
#define AUDIO_H
#include <jack/jack.h>
typedef jack_default_audio_sample_t sample_t;
typedef enum {
off,
on,
ramp_down,
ramp_up,
} b_state;
typedef struct {
float *data;
float gain;
b_state state;
} buffer_t;
extern buffer_t *buffers;
extern unsigned int buffer_size;
extern unsigned int num_buffers;
extern jack_client_t *client;
extern jack_port_t *output_port_ML;
extern jack_port_t *output_port_MR;
extern float gain_inc;
int process(jack_nframes_t nframes, void *arg);
#endif
//=================== clockloop.c =======================
/*
* Copyright (C) 2003 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
#include <sndfile.h>
#include "audio.h"
void midi_action(snd_seq_t * seq_handle);
jack_client_t *client;
jack_port_t *output_port_ML;
jack_port_t *output_port_MR;
int main(int argc, char **argv)
{
unsigned int i;
int count;
const char **ports;
if (argc < 2) {
fprintf(stderr, "Usage: %s <audio-file> ...\n", argv[0]);
return 1;
}
/* JACK stuff */
if ((client = jack_client_new("clock-loop")) == 0) {
fprintf (stderr, "jack server not running?\n");
return 1;
}
jack_set_process_callback (client, process, 0);
output_port_ML = jack_port_register (client, "out_Master_Left",
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
output_port_MR = jack_port_register (client, "out_Master_Right",
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
num_buffers = argc - 1;
buffers = malloc(sizeof(buffer_t) * num_buffers *
2); // *2 for stereo
buffer_size = 0;
for (i = 0; i<num_buffers; i++) {
SNDFILE *sf;
SF_INFO sfi;
sfi.format = 0;
sf = sf_open(argv[i + 1], SFM_READ, &sfi);
/*if (sfi.channels != 1) {
fprintf(stderr, "%s: only works with mono files\n", argv[0]);
return 1;
}*/
if (!buffer_size) {
buffer_size = sfi.frames;
gain_inc = (float)jack_get_buffer_size(client) /
(buffer_size * 8.0f);
buffers[i].state = on;
buffers[i].gain = 1.0f;
} else {
buffers[i].state = off;
buffers[i].gain = 0.0f;
}
if (sfi.frames > buffer_size) {
fprintf(stderr, "%s warning: '%s' is %d frames longer than
reference file, truncating\n", argv[0], argv[i+1], (int)(sfi.frames -
buffer_size));
}
buffers[i].data = malloc(buffer_size * sizeof(float));
count = sf_read_float(sf, buffers[i].data, buffer_size);
if (count < buffer_size) {
fprintf(stderr, "%s warning: only read %d/%d frames from
file '%s', zero padding\n", argv[0], count, buffer_size, argv[i+1]);
memset(buffers[i].data + count, 0, buffer_size - count);
}
sf_close(sf);
}
if (jack_activate(client)) {
fprintf (stderr, "cannot activate client");
exit(1);
}
/* connect the ports*/
if ((ports = jack_get_ports (client, NULL, NULL,
JackPortIsPhysical|JackPortIsInput)) == NULL) {
fprintf(stderr, "Cannot find any physical playback ports\n");
exit(1);
}
if (jack_connect (client, jack_port_name (output_port_ML),
ports[0])) {
fprintf (stderr, "cannot connect output ports\n");
}
if (jack_connect (client, jack_port_name (output_port_MR),
ports[1])) {
fprintf (stderr, "cannot connect output ports\n");
}
for(;;)
sleep (1);
}
I'm trying to find a good solution for realtime upsampling and eq effects.
So far it seems running jamin with jack enabled programs, and passing them
through jamin for processing will be the best program for adjusting eq
levels, and setting crossovers. In this area, information on other programs
I have missed is appricated.
I would then like to be able to take the sound and upsample it to dts for
5.1 or 7.1 surround sound, and being able to set delays for each speaker to
be able to tune the audio to the acoustics of the area. A perfect setup
would be able to to full eq/crossover/delay settings for each speaker while
doing live encodes, but any additional information on open source projects
related to these areas are appricated.
Thanks in advance,
Nathanael Anderson
Traverso 0.42.0 Release Announcement
The Traverso development team is pleased to announce the release of Traverso
0.42.0
About Traverso:
Traverso is a GPL licensed, cross platform program for recording and mixing
music, speech, and sounds on the computer
Important changes in this release:
* Read and write support for Ogg Vorbis, WavPack, FLAC and MP3
* On the fly sample rate conversion
* A simple yet effective Project backup and restore system
* Better use of available hard disk bandwidth
* Encoding formats for recording added: W64 and WavPack
* 3 new themes added, notably the medium-contrast and ubuntu theme
* Fixed a number of bugs, added new ones and various improvements all over the
place
* User Manual translated into German and Portuguese
Source tarball and installers for Mac OS X and Windows are available on the
download page [1]
Distribution packages are being created, with some (openSUSE, Gentoo) allready
available for installation.
We welcome any feedback in the forums [2], user mailing list [3] or internet
relay chat, channel #traverso
Enjoy!
The Traverso team.
[1] http://traverso-daw.org/
[2] http://traverso-daw.org/forum/
[3] http://savannah.nongnu.org/mail/?group=traverso
Rubber Band is an audio time-stretching and pitch-shifting library and
utility designed for musical applications.
http://www.breakfastquay.com/rubberband/
It includes a library that supports a sample-accurate multithreaded
offline mode and a real-time lock-free streaming mode; a command-line
utility program; and a LADSPA pitch-shifter plugin. Rubber Band is
Free Software under the GNU GPL.
Chris
Rubber Band is an audio time-stretching and pitch-shifting library and
utility designed for musical applications.
http://www.breakfastquay.com/rubberband/
It includes a library that supports a sample-accurate multithreaded
offline mode and a real-time lock-free streaming mode; a command-line
utility program; and a LADSPA pitch-shifter plugin. Rubber Band is
Free Software under the GNU GPL.
This small update (v1.0.1) fixes an option parsing bug and a dodgy
bit of #ifdef nesting. The core code is the same as in 1.0.
Chris
dssi-vst 0.5 released!
======================
The 0.5 release of dssi-vst is now available.
dssi-vst is a DSSI plugin wrapper for Win32 VST effects and instruments
with GUI support, allowing them to be loaded into any DSSI host.
dssi-vst is available from the download page at
http://dssi.sourceforge.net/
The 0.5 release now comes with Javier Serrano Polo's VST-compatibility
header, as previously distributed in LMMS. (Actually, this header was
already compatible with dssi-vst -- no modifications to dssi-vst were
necessary -- it's just that the header is now included in the package.)
This permits it to be compiled without the official VST SDK and
distributed under pure GPL. No guarantees are made as to the
reliability of the results; your feedback is welcome, but please bear
in mind that I will not do any development work on the compatibility
header myself for legal reasons.
The 0.5 release is also (finally) compatible with version 2.4r2 of the
official SDK, should you wish to use it.
Chris
Dave Robillard wrote:
> Why not make it satisfy most everyone by being extensible?
It *is* extensible. Note that commands 0x00-0x6F and 0x73-0x7F are
unused, so further extensions are free to define them (perhaps we need a
scheme for binding extension URIs to command numbers, to make it more
LV2-ey). And 0x72 command can be used for pretty much any data larger
than 8+2 octets.
While it's "efficient first" and not "generic first", so to speak, it
should be fine for the intended uses.
> The idea of a generic event port is not a bad one,
I think it's not just "not a bad one". The other possibility (multiple
event ports) is less efficient, and speed is crucial here. It's also
more complex, looking from plugin author's perspective. So I had little
choice.
> idea at all (no matter what, someone is going to want to put something
> in there you didn't think of.
Please don't jump to conclusions, and take more time to read and analyse
the proposal.
Of course, it is possible to add new event types with arbitrary length
data, and the limitation of 8 octets per extended block is not that bad,
because you can always fit an interface pointer (32-bit or 64-bit) there.
Just look how binary data extension is implemented.
Notice that I just took the approach of optimizing for most common case
(MIDI events), and tried to maximize functionality while keeping block
size small and constant (to avoid pointer arithmetic that was
complicating Lars' proposal a bit).
> Trying to pre-define things from the top down like this is un-lv2-ey).
Well, sometimes you need to find the right tradeoff between being
efficient (memory- and speed-wise) and generic. I think I've found an
acceptable tradeoff (definitely favouring speed, but not losing
generality and not very memory-hungry).
However, I had to make some assumptions about how it will be used
(mostly implemented by inexperienced people, mostly used for MIDI and
float parameters, seldom used for advanced stuff). Oh well, I'm
repeating myself here :)
I think those are correct assumptions, but you seem to have a different
angle for looking at those things. Well, it took me years (and
failed/inadequate designs) to grow out of the "everything should be as
generic as possible" approach, so I understand why you're doing that,
but I still prefer the priority-based optimization approach that I've used.
I still think my proposal could be improved, and I don't like some
decisions that I made (basically, I made them because the alternatives
looked even more nasty), but stripping off optimizations is not the way
to go, IMO.
> Something more appropriate (IMO) might be like:
> struct LV2_EVENT
> {
> ev_stamp_t time; ///< (ignoring the timestamp type issue)
> ev_type_t type; ///< (again ignoring type issue)
> size_t buf_size; ///< size of buf in bytes
> char* buf; ///< raw event data
> }
You're suggesting a "classic" textbook chunked data approach, which
works, no doubt. However, it has some problems with it, which might not
be considered very major, but seem to make my approach slightly more
favourable:
- too much data to be accessed in the most common use case (in 32-bit
environment, 16 bytes of header plus event data possibly in distant
memory); we don't need to save every byte of RAM, but when you need to
read and write twice as much RAM as you could, then maybe it's worth
rethinking it
- separation of event header and event data in the most common case; it
would be better not to cause cache thrashing too much
- it encourages memory fragmentation (experienced people will allocate
event data for all events in the same buffer, wonder about inexperienced
ones, one malloc per event data? :) )
- it doesn't deal with large data properly (because the plugin cannot
start "owning" the raw event data instead of copying it from the buffer
provided); imagine copying a video buffer in the process() function of a
plugin!
I'm not saying that approach is Really Bad - just that it's kind of a
pre-optimization version of my proposal (I made MIDI data very
efficient, float parameter data slightly less efficient, float parameter
data with deltas even less efficient, and binary data are pretty
inefficient :) ).
The fact that event has to be handled is annoying enough on its own :) -
I have to end the inner loop, store state information somewhere etc. - I
don't want some additional, unnecessary memory accesses which may throw
sample data and buffers out of the cache.
> (Obviously just a quick generic knock-off to get the idea across). In
> networkey terms, this is separating transport from contents, which is
> pretty firmly established as a Good Idea.
In network context, yes. However, _optimizing_ for uncommon case is not
a preferable approach to me.
The arbitrary binary data command (0x72) mentioned in my proposal can
give you practically everything you need, and can be used in a
network-transparent way, as long as data in the "binary data" chunks are
self-contained (don't refer to other buffers).
However, my proposal lacks any mechanism to be used for serializing
arguments of future commands defined by extensions.
Still, that problem was solved many times in history, by deriving extra
interfaces for the new commands from an interface that provides
reference counting and marshalling. IPersistStream type stuff, for the
victims of Microsoft APIs.
It is a bit complex (or at least not as trivial as plain MIDI), but it
would be only used in hosts and complex plugins that use extension
events, so I guess it'd be fine.
> I very strongly feel that if 'more than MIDI' events are going to be
> mixed with MIDI events in the same port (s/MIDI/whatever), then the
> event transport mechanism needs to be 100% event type agnostic.
On the other hand, "100% generic" means "almost 100% unoptimized". By
throwing away extra information, you often throw away the chances for
optimization, so to speak.
Instead of thinking in terms of MIDI vs non-MIDI, try thinking of "my"
event types as "short" (8 octets), "medium" (16 octets) and "large"
(arbitrary-sized blobs). The fact that all short events are MIDI events
is, I think, less important. It's also not set in stone.
> It's the same approach LV2 takes with ports, and it works beautifully there.
On the other hand, it deals with a trivial problem, and solves it in a
complex way. That's not an engineer's dream :)
Regards,
Krzysztof
midi application for midi control and note playing with a twist ( of the
wiimote ) here it is. <http://miidi.sourceforge.net>
Yannis Gravezas,
Athens, Greece