Reverb

Things that make the work with LinuxSampler & Co easier, better, faster, louder and more sexy. Including friends like JACK, ALSA, etc.
User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

Reverb

Post by dahnielson » Mon Feb 04, 2008 4:31 pm

Having the right reverb is just as important as having the right samples, especially if you are working with dry sampled instruments.

TAP Reverb
The TAP reverb comes in two editions: as a LADSPA plugin you use in you audio application and as a JACK client that you use to edit the presets giving you a lot more options than the plugins interface. Unfortunately this reverb is plagued with the common metallic tin-box sound making it less suitable for orchestral works.

Freeverb 3
The Freeverb distribution contain several types of reverbs, unfortunately none of them as a LADSPA plugin or JACK client. But the CMT LADSPA plugin collection do contain a port of the algorithmic reverb unit. To my suprise, after some fiddling with the wet control I actually managed to get a pretty pleasing concert hall result and I haven't detected any tin-box tendencies yet. Freeverb is very well tuned.

GVerb
Reverberation LADSPA plug-in written by Juhana Sadeharju and ported to LADSPA by Steve Harris. Haven't tested it yet but you can find some tips and tricks for it at the Audacity Wiki. Fons Adriaensen have made a stereo version of it distributed in the REV-Plugins bundle.

BruteFIR
A convolution engine for applying long FIR filters to multi-channel digital audio, either offline or in realtime. It's possible to set it up for realtime operation using JACK. Haven't managed to configure it so I can't tell how well it works, but it should produce very realistic result with a good set of impulse responses.

JConv
Convolution engine for JACK, by Fons Adriaensen, based on FFT convolution and using non-uniform partition sizes: small ones at the start of the IR and building up to the most efficient size further on. It can perform zero-delay processing with moderate CPU load. If you have trouble compiling it look further down this thread for the solution.

dssi_convolve
Convolution engine implemented as DSSI plugin to provide a custom GUI. Based on the authors libconvolve library. Due to some shortcomings of DSSI it is not possible to run dssi_convolve with the same partition size as the host and thus a zero-latency mode (additional latency that is) is not possible with this DSSI version.

jack_convolve
Convolution engine for JACK. Based on the authors libconvolve library. Can perform at zero-latency.

More discussion about JConv and mixing techniques here.
Last edited by dahnielson on Tue Sep 02, 2008 8:17 pm, edited 8 times in total.
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

Alex
Moderator
Posts: 316
Joined: Wed Jan 23, 2008 9:08 pm

Re: Reverb

Post by Alex » Mon Feb 04, 2008 9:17 pm

Thanks for this list Anders.
I couldn't build jconv either, so we're in the same boat here.
Would be nice if we could find a gui for it as well.
I'll keep looking.

We could do with a really decent convolution plugin or standalone programme.
Personally, i'd opt for a standalone, with jack ports in and out. Much easier to handle.

Alex.

8-)

User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

Re: Reverb

Post by dahnielson » Mon Feb 04, 2008 10:35 pm

BruteFIR is probably the prime candidate at the moment, if I only could figure out how to configure it to use my library of IR's in wav or aiff format.

I have tried the Freeverb convolver on files (it was really simple to use) and will see if I'm capable of wrapping it up as a JACK client and/or LADSPA plugin (meaning spending and hour or two on the project). They do offer a VST plugin but no LADSPA. :shock:
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

Re: Reverb

Post by dahnielson » Sun Feb 10, 2008 3:07 pm

Too tired to figure out why it's not working properly. Here's the code I've pilfered and stitched together:

Code: Select all

// To compile use:
//
//   g++ ire.cpp -o ire -I/usr/include -L/usr/lib  \
//   `pkg-config --cflags --libs jack`		       \
//   `pkg-config --cflags --libs freeverb3`        \
//   `pkg-config --cflags --libs sndfile`
//
// To run:
//
//   ./ire impulse.wav

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

#include <sndfile.h>
#include <irmodel.hpp>
#include <math.h>
#include <fftw3.h>

#include <jack/jack.h>

/*** Freeverb3 ***/

using namespace fv3;

irmodel reverbm;

SNDFILE* openImpulseFile(char * file, SF_INFO * sf)
{
	SNDFILE * sfp = sf_open(file, SFM_READ, sf);
	if(sfp == NULL)
	{
		fprintf(stderr, "sf_open: Couldn't load %s\n", file);
		exit(-1);
	}
	return sfp;
}

void readSoundFloat(SNDFILE * snd, float * f, int frames)
{
	int st = sf_readf_float(snd, f, frames);
	if(st != frames)
	{
		fprintf(stderr, "sf_readf_float: error\n");
		exit(-1);
	}
}

void splitLR(float * data, float * L, float * R, int singleSize)
{
	for(int t = 0; t < singleSize; t++)
	{
		L[t] = data[t*2+0];
		R[t] = data[t*2+1];
	}
}

/*** JACK ***/

jack_port_t *input_left;
jack_port_t *input_right;
jack_port_t *output_left;
jack_port_t *output_right;
jack_client_t *client;

int process(jack_nframes_t nframes, void *arg)
{
	jack_default_audio_sample_t *inL, *inR, *outL, *outR;
	inL = (jack_default_audio_sample_t *) jack_port_get_buffer(input_left, nframes);
	inR = (jack_default_audio_sample_t *) jack_port_get_buffer(input_right, nframes);
	outL = (jack_default_audio_sample_t *) jack_port_get_buffer(output_left, nframes);
	outR = (jack_default_audio_sample_t *) jack_port_get_buffer(output_right, nframes);
	reverbm.processreplace(inL, inR, outL, outR, nframes, 1);
	return 0;
}

void jack_shutdown(void *arg)
{
	exit(1);
}

int main(int argc, char **argv)
{
	if (argc < 2)
	{
		exit(-1);
	}

	SNDFILE * irSND = NULL;
	SF_INFO rsfinfo;
	float *irL, *irR;
	
	irSND = openImpulseFile(argv[1], &rsfinfo);
	float tmp[rsfinfo.frames*rsfinfo.channels];
	irL = new float[rsfinfo.frames];
	irR = new float[rsfinfo.frames];
	
	readSoundFloat(irSND, tmp, rsfinfo.frames);
	
        if(rsfinfo.channels == 1)
	{
		memcpy(irL, tmp, sizeof(float)*rsfinfo.frames);
		memcpy(irR, tmp, sizeof(float)*rsfinfo.frames);
	}
	else if(rsfinfo.channels == 2)
	{
		splitLR(tmp, irL, irR, rsfinfo.frames);
	}
	else
	{
		fprintf(stderr, "cannot handle: rsfinfo.channels > 2\n");
		exit(-1);
	}

	fprintf(stderr, "loadImpulse(sample = %lld,FFTW_ESTIMATE)...", rsfinfo.frames);
	reverbm.loadImpulse(irL, irR, rsfinfo.frames, FFTW_ESTIMATE, 0);
	delete[] irL;
	delete[] irR;
	fprintf(stderr, "done.\n");
	fprintf(stderr, "latency = %d\n", reverbm.getLatency());
	fprintf(stderr, "internal FFT size = %d x 2\n", reverbm.getSampleSize());

	reverbm.setwet(.5);
	reverbm.setdry(.5);
	reverbm.setwidth(0.5);
	
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;

	client_name = "ire";
	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);
	}

	jack_set_process_callback(client, process, 0);
	jack_on_shutdown(client, jack_shutdown, 0);
	
	input_left = jack_port_register(client, "inL",
					JACK_DEFAULT_AUDIO_TYPE,
					JackPortIsInput, 0);
	input_right = jack_port_register(client, "inR",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_left = jack_port_register(client, "outL",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsOutput, 0);
	output_right = jack_port_register(client, "outR",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);
	
	if ((input_left == NULL) || (input_right == NULL) 
	    || (output_left == NULL) || (output_right == NULL))
	{
		fprintf(stderr, "no more JACK ports available\n");
		exit(1);
	}

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

	while(1)
		sleep(1);

	jack_client_close(client);
	exit(0);
}
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

Re: Reverb

Post by dahnielson » Thu Feb 14, 2008 8:40 pm

Just thought this might be of interest to some, despite the fact we're lacking a working convolution reverb to begin with:

http://emusician.com/tutorials/emusic_acting_impulse/
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

How to get jconv to work!

Post by dahnielson » Sat Feb 16, 2008 12:29 am

I did send out a plea for help to the LAD community and received help to get jconv to compile. It's quite simple actually:

* The reason that the build fails is because jconv relies on a pre-release version of libsndfile that contain support for ambisonic file formats.

* The solution is to edit a single line in the Makefile so it looks like this:

Code: Select all

# Uncomment if you use a libsndfile version without support for setting/getting the Ambisonic flags.
CPPFLAGS += -DNOAMBIS=1
There was a freaking comment about it and I missed it while editing the prefix to /usr/local ten lines above it !!!
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

w1teru
Newbie
Posts: 2
Joined: Sat Feb 16, 2008 3:27 am

Re: Reverb

Post by w1teru » Sat Feb 16, 2008 3:32 am

> Too tired to figure out why it's not working properly.
> Here's the code I've pilfered and stitched together:

You should use irmodel2(irmodel2.hpp) or irmodel3(irmodel3.hpp),
which are SIMD(SSE/SSE2/3DNow!)
optimized and zerolatency version.

User avatar
dahnielson
Moderator
Posts: 632
Joined: Wed Jan 23, 2008 11:25 pm
Location: Linköping / Tranås, Sweden
Contact:

Re: Reverb

Post by dahnielson » Sat Feb 16, 2008 2:35 pm

w1teru wrote:> Too tired to figure out why it's not working properly.
> Here's the code I've pilfered and stitched together:

You should use irmodel2(irmodel2.hpp) or irmodel3(irmodel3.hpp),
which are SIMD(SSE/SSE2/3DNow!)
optimized and zerolatency version.
Thanks for the advice! :)
Anders Dahnielson

Ardour2, Qtractor, Linuxsampler, M-AUDIO Delta 1010, Axiom 61, Korg D12, AKAI S2000, E-MU Proteus 2k, Roland R-5, Roland HP 1300e, Zoom RFX-1000, 4GB RAM x86_64 Intel Pentium Dual 1.80GHz Gentoo Linux

w1teru
Newbie
Posts: 2
Joined: Sat Feb 16, 2008 3:27 am

Re: Reverb

Post by w1teru » Sat Feb 16, 2008 3:18 pm

If there were some needs of the JACK client and LADSPA plugin,
I want to add your JACK/LADSPA source code to Freeverb3 in the next release.
Unfortunately, I am not familiar with JACK or LADSPA :-(

Alex
Moderator
Posts: 316
Joined: Wed Jan 23, 2008 9:08 pm

Re: LADSPA plugins

Post by Alex » Sun Feb 17, 2008 10:12 pm

Hello Anders!

Thanks for posting the links. Highly useful indeed.
Just an update here, i got jconv compiled and loaded, and as i understand it, StudioDave is going to ask Fons how far along he's got with a GUI for this.
So you may well have another link to add to your illustrious list!
A convolution plug with user loadable IR's in an interface that's easy to use would, imho, be a big plus for Linuxsampler use.

Alex.

:)

Post Reply