[linux-audio-user] [ANNOUNCE] jack_convolve-0.0.1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Florian,

Just gave your dry and wet sample a quick listen. It
sounds promising. I'm looking forward to giving it a
more serious run.

ron

--- Florian Schmidt <mista.tapas@xxxxxxx> wrote:

> 
> Hi,
> 
> i implemented a small convolution engine for jack..
> grab it at
> 
> http://affenbande.org/~tapas/jack_convolve-0.0.1.tgz
> 
> untar
> make
> ./jack_convolve responsefile.wav
> 
> It creates as many in/out ports as the response file
> has channels. Uses
> fftw3f and libsndfile. Will add libsamplerate
> support in near future.
> So for now, make sure the samplerate of jack and the
> response file
> match.
> 
> Here's a ca 1 sec 48khz (resampled from 96khz)
> stereo response file of a
> room:
> 
>
http://affenbande.org/~tapas/FrontFacing%20TLM170.wav
> 
> It's from this package:
> 
>
http://www.noisevault.com/index.php?page=3&action=file&file_id=130
> 
> which has 96khz responses..
> 
> Consumes ca. 25-30% cpu load on my 1.2ghz athlon at
> jack buffer size 2048
> [;)]
> 
> So there's plenty room for optimization (and some
> return value checking
> will be added too ;)).. If you know some tricks, let
> me know.. The
> sourcecode is pasted below for easier reference. 
> 
> Flo
> 
> P.S.: thanks to mario lang for collaborating and
> giving some hints
> towards using fftw3f instead of fftw and some other
> optimizations..
> 
> P.P.S.: oh yeah, example sound, here you go
> [hydrogen dry then with
> output of jack_convolve mixed to it]:
> 
> http://affenbande.org/~tapas/jack_conv_ex1.ogg
> 
> And here the convoluted signal alone:
> 
> http://affenbande.org/~tapas/jack_conv_ex2.ogg
> 
> P.P.S.: known issues: 
> 
> - won't handle samplerate or buffersize changes
> gracefully
> 
> - will bring your machine to a crawl ;)
> 
> 
> jack_convolve.cc:
> ---------------
> 
> /*
>     Copyright (C) 2004 Florian Schmidt
>     
>     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.
> 
>     $Id: types_8h-source.html,v 1.1 2004/04/27
> 18:21:48 joq Exp $
> */
>  
> 
> 
> #include <jack/jack.h>
> #include <iostream>
> #include <sstream>
> #include <unistd.h>
> #include <signal.h>
> #include <stdio.h>
> #include <sndfile.h>
> #include <vector>
> #include <cmath>
> #include <fftw3.h>
> 
> jack_client_t *client;
> 
> std::vector<jack_port_t *> iports;
> std::vector<jack_port_t *> oports;
> 
> jack_nframes_t jack_buffer_size;
> int chunks_per_channel;
> 
> // channel   chunk         data
> std::vector<std::vector <fftwf_complex*> > chunks;
> 
> // the buffers for the fft
> float *fft_float;
> fftwf_complex *fft_complex;
> 
> // the plan
> fftwf_plan fft_plan_forward;
> fftwf_plan fft_plan_backward;
> 
> float normalize_factor;
> 
> // per channel we need a ringbuffer holding the fft
> results of the 
> // audio periods passed to us by jackd.
> // each needs to be sized jack_buffer_size *
> chunks_per_channel (see main())
> std::vector<fftwf_complex *> ringbuffers;
> 
> // this gets advanced by jack_buffer_size after each
> process() callback 
> unsigned int ringbuffer_index = 0;
> 
> // a vector to hold the jack buffer pointers.. these
> get resized
> // during init in main
> std::vector<jack_default_audio_sample_t *> ibuffers;
> std::vector<jack_default_audio_sample_t *> obuffers;
> 
> // channel     data
> std::vector<jack_default_audio_sample_t *>overlaps;
> 
> int process(jack_nframes_t frames, void *arg) {
> 	// std::cout << " " << ringbuffer_index;
> 	// get pointer[s] to the buffer[s]
> 	int channels = chunks.size();
> 	
> 	for (int channel = 0; channel < channels;
> ++channel) {	
> 		ibuffers[channel] =
>
((jack_default_audio_sample_t*)jack_port_get_buffer(iports[channel],
> frames));
> 		obuffers[channel] =
>
((jack_default_audio_sample_t*)jack_port_get_buffer(oports[channel],
> frames));
> 	}
> 
> 	for (int channel = 0; channel < channels;
> ++channel) {
> 		// copy input buffer to fft buffer		
> 		for (int frame = 0; frame < jack_buffer_size;
> ++frame) {
> 			fft_float[frame] =
> (float)(ibuffers[channel][frame]);
> 			fft_float[frame+jack_buffer_size] = 0.0;
> 		}
> 		// fft the input[s]
> 		fftwf_execute(fft_plan_forward);
> 
> 		// store the new result into the ringbuffer for
> this channel
> 		for (int frame = 0; frame < jack_buffer_size * 2;
> ++frame) {
> 			ringbuffers[channel][ringbuffer_index+frame][0] =
> fft_complex[frame][0] / normalize_factor;
> 			ringbuffers[channel][ringbuffer_index+frame][1] =
> fft_complex[frame][1] / normalize_factor;
> 		}
> 
> 		// zero our buffer for the inverse FFT, so we can
> simply += the
> 		// values in the next step.
> 		for (int frame = 0; frame < jack_buffer_size * 2;
> ++frame) {
> 			fft_complex[frame][0] = 0;
> 			fft_complex[frame][1] = 0;
> 		}
> 
> 
=== message truncated ===



		
__________________________________ 
Do you Yahoo!? 
Take Yahoo! Mail with you! Get it on your mobile phone. 
http://mobile.yahoo.com/maildemo 

[Index of Archives]     [Linux Sound]     [ALSA Users]     [Pulse Audio]     [ALSA Devel]     [Sox Users]     [Linux Media]     [Kernel]     [Photo Sharing]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux