Update of /cvsroot/foo/foo/libfoo/modules In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv7604 Modified Files: Makefile.am Added Files: FOOMAdd.h FOOMAdd.m FOOMAllpass.h FOOMAllpass.m FOOMBandlimitedNoise.h FOOMBandlimitedNoise.m FOOMComb.h FOOMComb.m FOOMConstant.h FOOMConstant.m FOOMConstantBiquad.h FOOMConstantBiquad.m FOOMConstantTwoPole.h FOOMConstantTwoPole.m FOOMConstantTwoPoleTwoZero.h FOOMConstantTwoPoleTwoZero.m FOOMDiff.h FOOMDiff.m FOOMDirac.h FOOMDirac.m FOOMDiv.h FOOMDiv.m FOOMExpon.h FOOMExpon.m FOOMFiltreVariableEtat.h FOOMFiltreVariableEtat.m FOOMFof.h FOOMFof.m FOOMGate.h FOOMGate.m FOOMInteg.h FOOMInteg.m FOOMKillDC.h FOOMKillDC.m FOOMLine.h FOOMLine.m FOOMLookup.h FOOMLookup.m FOOMMath.h FOOMMath.m FOOMMul.h FOOMMul.m FOOMNeg.h FOOMNeg.m FOOMNoise.h FOOMNoise.m FOOMOscillator.h FOOMOscillator.m FOOMReadBpf.h FOOMReadBpf.m FOOMReadSnd.h FOOMReadSnd.m FOOMReadTranspSnd.h FOOMReadTranspSnd.m FOOMReverb.h FOOMReverb.m FOOMReverb8.h FOOMReverb8.m FOOMReverbOutput.h FOOMReverbOutput.m FOOMSub.h FOOMSub.m FOOMTransposeBpf.h FOOMTransposeBpf.m FOOMTransposeSnd.h FOOMTransposeSnd.m FOOMVariableTwoPole.h FOOMVariableTwoPole.m Log Message: relocated modules --- NEW FILE: FOOMLookup.h --- /* -*-Mode:objc-*- */ /* * FOOMLookup.h * * module lookup * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMLookup.h,v 1.1 2007/12/14 14:16:12 rumori Exp $ */ #ifndef FOOM_FOOMLOOKUP_H_INCLUDED #define FOOM_FOOMLOOKUP_H_INCLUDED #include <FOO/FOOEagerModule.h> #include <FOO/FOOSubstrate.h> #include <FOO/FOOLookupTable.h> @interface FOOMLookup : FOOEagerModule <NSCoding> { /* Substrate *substrate; // statically typed */ id _substrate; sample_t *_samples; int _offset; int _count; int _taps; FOOLookupTable *_table; } - initializeWith: (FOOSubstrate *)substr taps: (int)n; @end #endif /* #ifndef FOOM_FOOMLOOKUP_H_INCLUDED */ --- NEW FILE: FOOMLookup.m --- /* -*-Mode:objc-*- */ /* * FOOMLookup.m * * module lookup * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMLookup.m,v 1.1 2007/12/14 14:16:12 rumori Exp $ */ #include "FOOMLookup.h" #include <FOO/FOOSoundFile.h> #include <FOO/FOOSoundStream.h> #include <FOO/FOORegion.h> #define SAMPLE_BUFFER_SIZE 1024 // should be several times the taps size @implementation FOOMLookup - initializeWith: (FOOSubstrate *)substr taps: (int)n { if ([substr isKindOfClass: [FOOSoundFile class]] == NO && [substr isKindOfClass: [FOOSoundStream class]] == NO && [substr isKindOfClass: [FOORegion class]] == NO) { FOO_ERROR(YES, self); } _substrate = substr; _taps = n; _count = SAMPLE_BUFFER_SIZE; _offset = -_count; _samples = NSZoneCalloc([self zone], _count, sizeof(sample_t)); _table = [FOOGlobalsManager getSineXoverXTable: _taps]; return self; } - (void) dealloc { NSZoneFree([self zone], _samples); [super dealloc]; } - reset { [super reset]; memset(_samples, 0, _count * sizeof(sample_t)); _offset = -_count; return self; } - (BOOL) activate { if ([_inputs count] == 0) { return (_active = NO); } _active = [[_inputs objectAtIndex: 0] activate]; return _active; } - (BOOL) compute { id m; sample_t *sb, *in, *out, *base, *delta; double sr, pos, sdelta; int n, tinc, size, ipos, cot, tot; COMPUTE_PROLOGUE; m = [_inputs objectAtIndex: 0]; [m compute]; n = BLOCKSIZE; sr = SAMPLERATE; sb = _samples; in = [[m getBuffer] data]; out = [_buffer data]; tot = _taps / 2; cot = _count / 2; size = [_substrate size]; base = [_table getBase]; delta = [_table getDelta]; tinc = [_table getSize] / tot; while (n--) { pos = *in++ * sr; ipos = (int) pos; sdelta = pos - ipos; if (ipos >= size || ipos < 0) { // not completely correct *out++ = 0; continue; } if (ipos >= _offset + _count || ipos < _offset) { _offset = ipos - cot; ipos = cot; [_substrate getSamples: sb offset: _offset size: _count]; } else { ipos -= _offset; if (ipos > (_count - tot)) { int f = ipos - cot + 1; int r = _count - f; bcopy(sb + f, sb, r * sizeof(sample_t)); _offset += f; ipos = cot - 1; [_substrate getSamples: sb + r offset: _offset + r size: f]; } else if (ipos < tot) { bcopy(sb + ipos, sb + cot, cot * sizeof(sample_t)); _offset -= cot - ipos; ipos = cot; [_substrate getSamples: sb offset: _offset size: cot]; } } { sample_t *s = sb + ipos; double fti = sdelta * tinc; // has to be double ! int ti1 = (int) fti, ti2 = tinc - ti1 - 1, si; double tdelta = fti - ti1, sum = 0; // idem for (si = 0; si > -tot; si--, ti1 += tinc) { sum += s[si] * (base[ti1] + delta[ti1] * tdelta); } tdelta = 1 - tdelta; for (si = 1; si <= tot; si++, ti2 += tinc) { sum += s[si] * (base[ti2] + delta[ti2] * tdelta); } *out++ = sum; } } COMPUTE_EPILOGUE; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeObject: _substrate forKey: @"FOOMLookup:substrate"]; [coder encodeInt: _offset forKey: @"FOOMLookup:offset"]; [coder encodeInt: _count forKey: @"FOOMLookup:count"]; [coder encodeInt: _taps forKey: @"FOOMLookup:taps"]; } else { [coder encodeObject: _substrate]; [coder encodeValueOfObjCType: @encode(int) at: &_offset]; [coder encodeValueOfObjCType: @encode(int) at: &_count]; [coder encodeValueOfObjCType: @encode(int) at: &_taps]; } return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if ([coder allowsKeyedCoding]) { _substrate = RETAIN([coder decodeObjectForKey: @"FOOMLookup:substrate"]); _offset = [coder decodeIntForKey: @"FOOMLookup:offset"]; _count = [coder decodeIntForKey: @"FOOMLookup:count"]; _taps = [coder decodeIntForKey: @"FOOMLookup:taps"]; } else { _substrate = RETAIN([coder decodeObject]); [coder decodeValueOfObjCType: @encode(int) at: &_offset]; [coder decodeValueOfObjCType: @encode(int) at: &_count]; [coder decodeValueOfObjCType: @encode(int) at: &_taps]; } _samples = NSZoneCalloc([self zone], _count, sizeof(sample_t)); _table = [FOOGlobalsManager getSineXoverXTable: _taps]; return self; } @end --- NEW FILE: FOOMConstant.h --- /* -*-Mode:objc-*- */ /* * FOOMConstant.h * * module constant * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMConstant.h,v 1.1 2007/12/14 14:16:08 rumori Exp $ */ #ifndef FOOM_FOOMCONSTANT_H_INCLUDED #define FOOM_FOOMCONSTANT_H_INCLUDED #include <FOO/FOOModule.h> @interface FOOMConstant : FOOModule <NSCoding> { sample_t _value; } - setValue: (sample_t)aValue; - (sample_t) getValue; @end #endif /* #ifndef FOOM_FOOMCONSTANT_H_INCLUDED */ --- NEW FILE: FOOMMul.m --- /* -*-Mode:objc-*- */ /* * FOOMMul.m * * modules mul * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMMul.m,v 1.1 2007/12/14 14:16:13 rumori Exp $ */ #include "FOOMMul.h" @implementation FOOMMul - (BOOL) activate { int i; if (INPUTS == 0) { return (_active = NO); } for (i = 0; i < INPUTS; i++) { if ([INPUT(i) activate] == NO) { return (_active = NO); } } return (_active = YES); } - (BOOL) compute { int i; id m; COMPUTE_PROLOGUE; m = INPUT(0); [m compute]; [_buffer mov: [m getBuffer]]; for (i = 1; i < INPUTS; ++i) { m = INPUT(i); [m compute]; [_buffer mul: [m getBuffer]]; } COMPUTE_EPILOGUE; } - (int) incrementBuffer { return 0; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; return self; } @end --- NEW FILE: FOOMDiv.m --- /* -*-Mode:objc-*- */ /* * FOOMDiv.m * * module div * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMDiv.m,v 1.1 2007/12/14 14:16:11 rumori Exp $ */ #include "FOOMDiv.h" @implementation FOOMDiv - (BOOL) activate { int i; if (INPUTS == 0) { return (_active = NO); } for (i = 0; i < INPUTS; i++) { if ([INPUT(i) activate] == NO) { return (_active = NO); } } return (_active = YES); } - (BOOL) compute { int i; id m; COMPUTE_PROLOGUE; m = INPUT(0); [m compute]; [_buffer mov: [m getBuffer]]; for (i = 1; i < [_inputs count]; i++) { m = INPUT(i); [m compute]; [_buffer div:[m getBuffer]]; } COMPUTE_EPILOGUE; } - (int)incrementBuffer { return 0; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; return self; } @end --- NEW FILE: FOOMReadTranspSnd.h --- /* -*-Mode:objc-*- */ /* * FOOMReadTranspSnd.h * * module readtranspsnd * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMReadTranspSnd.h,v 1.1 2007/12/14 14:16:14 rumori Exp $ */ #ifndef FOOM_FOOMREADTRANSPSND_H_INCLUDED #define FOOM_FOOMREADTRANSPSND_H_INCLUDED #include <FOO/FOOEagerModule.h> #include <FOO/FOOSoundStream.h> #include <FOO/FOOSoundFile.h> #include <FOO/FOORegion.h> #include <FOO/FOOLookupTable.h> @interface FOOMReadTranspSnd : FOOEagerModule <NSCoding> { id _substrate; /* input */ /* Substrate *substrate; /\* input *\/ */ sample_t *_samples; /* cache */ int _offset; /* cache's sample position in input */ int _count; /* size of cache */ int _endCache; /* end of cache */ int _taps; /* # of zero-crossings in sinc used for resampling */ FOOLookupTable *_table; /* sinc */ int _begin; /* begin time */ int _end; /* end time */ double _position; /* sample position in input */ double _beginT; /* begin time in seconds */ double _factor; /* transposition factor */ } - initializeWith: substr; - initializeTaps: (int)n; - initPos; - (BOOL)computeRead; - (BOOL)computeTransp; @end #endif /* #ifndef FOOM_FOOMREADTRANSPSND_H_INCLUDED */ --- NEW FILE: FOOMTransposeSnd.m --- /* -*-Mode:objc-*- */ /* * FOOMTransposeSnd.m * * module transpose sound * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMTransposeSnd.m,v 1.1 2007/12/14 14:16:16 rumori Exp $ */ #include "FOOMTransposeSnd.h" #define ROLL_OFF_FREQU 0.9 #define SAMPLE_BUFFER_SIZE 1024 // should be several times the taps size @implementation FOOMTransposeSnd - initializeWith: substr taps: (int) n { if ([substr isKindOfClass: [FOOSoundFile class]] == NO && [substr isKindOfClass: [FOOSoundStream class]] == NO && [substr isKindOfClass: [FOORegion class]] == NO) { FOO_ERROR(YES, self); } _substrate = substr; _beginT = TIMEFRAME; _taps = n; _count = SAMPLE_BUFFER_SIZE; if (_taps >= _count) { FOO_ERROR(YES, self); } _samples = NSZoneCalloc([self zone], _count, sizeof(sample_t)); _table = [FOOGlobalsManager getSineXoverXTable:_taps]; [self initPos]; return self; } - initPos { _position = 0; _offset = -_count; _end = _offset + _count; return self; } - (void) dealloc { if (_samples != NULL) { NSZoneFree([self zone], _samples); } [super dealloc]; } - reset { [super reset]; memset(_samples, 0, _count * sizeof(sample_t)); [self initPos]; return self; } - startUp { [super startUp]; _begin = SEC_TO_SAM(_beginT); _factor = [_substrate getSamplingRate] / SAMPLERATE; return self; } - (BOOL) activate { if (INPUTS == 0 || _begin >= BLOCKEND || _position - _taps > [_substrate size]) { return (_active = NO); } _active = [INPUT(0) activate]; return _active; } - (BOOL) compute { id m; int b, n, tinc, tot; double p; sample_t *in, *out, *base, *delta; int maxtot = _count / 2; COMPUTE_PROLOGUE; m = [_inputs objectAtIndex: 0]; [m compute]; n = BLOCKSIZE; in = [[m getBuffer] data]; out = [_buffer data]; tot = _taps / 2; if (tot > maxtot) { FOO_ERROR(NO, YES); tot = maxtot; } tinc = [_table getSize] / tot; base = [_table getBase]; delta = [_table getDelta]; if (_begin > SAMPLETIME) { b = _begin - SAMPLETIME; memset(out, 0, b * sizeof(sample_t)); in += b; out += b; n -= b; } while (n--) { p = *in++ * _factor; if (p < 0) { p = -p; } if (p > 1) { /* down sampling */ sample_t *s; double lp = p / ROLL_OFF_FREQU; double P = (_position - ((int)_position)) / lp; double ptinc = tinc / lp; double fti, sum = 0; int ti, si, ptot = tot * lp; if (ptot > maxtot) { FOO_ERROR(NO, YES); ptot = maxtot; } if (_end <= _position + ptot) { _offset = _position - ptot + 1; _end = _offset + _count; [_substrate getSamples:_samples offset:_offset size:_count]; } s = _samples + ((int)_position - _offset); for (fti = P * tinc, si = 0; si < ptot; si++, fti += ptinc) { ti = (int)fti; sum += s[-si] * (base[ti] + delta[ti] * (fti - ti)); } P = 1. / lp - P; for (fti = P * tinc, si = 1; si <= ptot; si++, fti += ptinc) { ti = (int)fti; sum += s[si] * (base[ti] + delta[ti] * (fti - ti)); } *out++ = sum / lp; } else { /* over sampling */ sample_t *s; double P = _position - ((int)_position); double fti = P * tinc; int ti1 = (int) fti, ti2 = tinc - ti1 - 1, si; double tdelta = fti - ti1, sum = 0; if (_end < _position + tot) { _offset =_position - tot + 1; _end = _offset + _count; [_substrate getSamples:_samples offset:_offset size:_count]; } s = _samples + ((int)_position - _offset); for (si = 0; si > -tot; si--, ti1 += tinc) { sum += s[si] * (base[ti1] + delta[ti1] * tdelta); } tdelta = 1 - tdelta; for (si = 1; si <= tot; si++, ti2 += tinc) { sum += s[si] * (base[ti2] + delta[ti2] * tdelta); } *out++ = sum; } _position += p; } COMPUTE_EPILOGUE; } - (int)getTimeInterval: (double*)b : (double*)e { *b = _beginT; return (TI_BEG); } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeObject: _substrate forKey: @"FOOMTransposeSnd:substrate"]; [coder encodeDouble: _beginT forKey: @"FOOMTransposeSnd:beginT"]; [coder encodeInt: _count forKey: @"FOOMTransposeSnd:count"]; [coder encodeInt: _taps forKey: @"FOOMTransposeSnd:taps"]; } else { [coder encodeObject: _substrate]; [coder encodeValueOfObjCType: @encode(double) at: &_beginT]; [coder encodeValueOfObjCType: @encode(int) at: &_count]; [coder encodeValueOfObjCType: @encode(int) at: &_taps]; } return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if ([coder allowsKeyedCoding]) { _substrate = RETAIN([coder decodeObjectForKey: @"FOOMTransposeSnd:substrate"]); _beginT = [coder decodeDoubleForKey: @"FOOMTransposeSnd:beginT"]; _count = [coder decodeIntForKey: @"FOOMTransposeSnd:count"]; _taps = [coder decodeIntForKey: @"FOOMTransposeSnd:taps"]; } else { _substrate = RETAIN([coder decodeObject]); [coder decodeValueOfObjCType: @encode(double) at: &_beginT]; [coder decodeValueOfObjCType: @encode(int) at: &_count]; [coder decodeValueOfObjCType: @encode(int) at: &_taps]; } _samples = NSZoneCalloc([self zone], _count, sizeof(sample_t)); _table = [FOOGlobalsManager getSineXoverXTable: _taps]; return [self initPos]; } @end --- NEW FILE: FOOMNeg.m --- /* -*-Mode:objc-*- */ /* * FOOMNeg.m * * modules neg * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMNeg.m,v 1.1 2007/12/14 14:16:13 rumori Exp $ */ #include "FOOMNeg.h" @implementation FOOMNeg - (BOOL) activate { if (INPUTS == 0) { return (_active = NO); } _active = [INPUT(0) activate]; return _active; } - (BOOL) compute { sample_t *in, *out; int n = BLOCKSIZE; COMPUTE_PROLOGUE; [INPUT(0) compute]; in = DATA_OF_MOD(INPUT(0)); out = DATA_OF_BUF(_buffer); while (n--) { *out++ = - *in++; } COMPUTE_EPILOGUE; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; return self; } @end --- NEW FILE: FOOMReadTranspSnd.m --- /* -*-Mode:objc-*- */ /* * FOOMReadTranspSnd.m * * module reverb * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMReadTranspSnd.m,v 1.1 2007/12/14 14:16:14 rumori Exp $ */ #include "FOOMReadTranspSnd.h" // defined in <GNUstepBase/preface.h> #ifndef ABS #define ABS(x) ((x) > 0 ? (x) : (-x)) #endif #define ROLL_OFF_FREQU 0.9 #define SAMPLE_BUFFER_SIZE 1024 // should be several times the taps size @implementation FOOMReadTranspSnd - init { [super init]; _samples = NULL; return self; } - initializeWith: substr { if ([substr isKindOfClass: [FOOSoundFile class]] == NO && [substr isKindOfClass: [FOOSoundStream class]] == NO && [substr isKindOfClass: [FOORegion class]] == NO) { FOO_ERROR(YES, self); } _substrate = substr; _beginT = TIMEFRAME; _taps = 0; [self initPos]; return self; } - initializeTaps: (int)n { _taps = n; _count = SAMPLE_BUFFER_SIZE; if (_taps < 4 || _taps >= _count) { FOO_ERROR(YES, self); } if (_samples != NULL) { NSZoneFree([self zone], _samples); } _samples = NSZoneCalloc([self zone], _count, sizeof(sample_t)); _table = [FOOGlobalsManager getSineXoverXTable:_taps]; [self initPos]; return self; } - initializeWith:substr taps: (int)n { [self initializeWith:substr]; [self initializeTaps:n]; return self; } - (void) dealloc { if (_samples != NULL) { NSZoneFree([self zone], _samples); } [super dealloc]; } - initPos { _position = 0; if (_taps != 0) { _offset = -_count; _endCache = _offset + _count; } return self; } - reset { [super reset]; [self initPos]; return self; } - startUp { [super startUp]; _begin = SEC_TO_SAM(_beginT); _end = _begin + [_substrate size]; if ([_substrate getSamplingRate] != SAMPLERATE) { _factor = [_substrate getSamplingRate] / SAMPLERATE; [self initializeTaps:[FOOGlobalsManager getDefaultTaps]]; } else { _factor = 1; } return self; } - (BOOL) activate { if (_taps == 0) { if (_begin >= BLOCKEND || _end < SAMPLETIME) _active = NO; else _active = YES; } else { if (_begin >= BLOCKEND || _position - _taps >= [_substrate size]) { _active = NO; } else { _active = YES; } } return _active; } - (BOOL)compute { if (_taps == 0) { return [self computeRead]; } else { return [self computeTransp]; } } - (BOOL)computeRead { sample_t *p; int b, e, s; COMPUTE_PROLOGUE; p = DATA_OF_BUF(_buffer); if (_begin > SAMPLETIME) { b = _begin - SAMPLETIME; memset(p, 0, b * sizeof(sample_t)); } else { b = 0; } if (_end < BLOCKEND) { e = BLOCKSIZE - (BLOCKEND - _end); memset(p + e, 0, (BLOCKSIZE - e) * sizeof(sample_t)); } else { e = BLOCKSIZE; } s = e - b; if ([_substrate getSamples: p + b offset: _position size: s] == NO) { FOO_ERROR(NO, _active); } _position += s; COMPUTE_EPILOGUE; } - (BOOL)computeTransp { int n, b, tinc, tot; double p; sample_t *out, *base, *delta; int maxtot = _count / 2; COMPUTE_PROLOGUE; n = BLOCKSIZE; out = [_buffer data]; tot = _taps / 2; if (tot > maxtot) { FOO_ERROR(NO, YES); tot = maxtot; } tinc = [_table getSize] / tot; base = [_table getBase]; delta = [_table getDelta]; if (_begin > SAMPLETIME) { b = _begin - SAMPLETIME; memset(out, 0, b * sizeof(sample_t)); out += b; n -= b; } p = _factor; if (p < 0) { p = -p; } while (n--) { if (p > 1) { /* down sampling */ sample_t *s; double lp = p / ROLL_OFF_FREQU; double P = (_position - ((int)_position)) / lp; double ptinc = tinc / lp; double fti, sum = 0; int ti, si, ptot = tot * lp; if (ptot > maxtot) { FOO_ERROR(NO, YES); ptot = maxtot; } if (_endCache <= _position + ptot) { _offset = _position - ptot + 1; _endCache = _offset + _count; [_substrate getSamples:_samples offset:_offset size:_count]; } s = _samples + ((int)_position - _offset); for (fti = P * tinc, si = 0; si < ptot; si++, fti += ptinc) { ti = (int) fti; sum += s[-si] * (base[ti] + delta[ti] * (fti - ti)); } P = 1. / lp - P; for (fti = P * tinc, si = 1; si <= ptot; si++, fti += ptinc) { ti = (int) fti; sum += s[si] * (base[ti] + delta[ti] * (fti - ti)); } *out++ = sum / lp; } else { /* over sampling */ sample_t *s; double P = _position - ((int)_position); double fti = P * tinc; int ti1 = (int) fti, ti2 = tinc - ti1 - 1, si; double tdelta = fti - ti1, sum = 0; if (_endCache < _position + tot) { _offset = _position - tot + 1; _endCache = _offset + _count; [_substrate getSamples:_samples offset:_offset size:_count]; } s = _samples + ((int)_position - _offset); for (si = 0; si > -tot; si--, ti1 += tinc) { sum += s[si] * (base[ti1] + delta[ti1] * tdelta); } tdelta = 1 - tdelta; for (si = 1; si <= tot; si++, ti2 += tinc) { sum += s[si] * (base[ti2] + delta[ti2] * tdelta); } *out++ = sum; } _position += p; } COMPUTE_EPILOGUE; } - (int)getTimeInterval:(double*)b :(double*)e { *b = _beginT; *e = _beginT + [_substrate size] / [_substrate getSamplingRate]; return (TI_BEG_END); } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeObject: _substrate forKey: @"FOOMReadTranspSnd:substrate"]; [coder encodeDouble: _beginT forKey: @"FOOMReadTranspSnd:beginT"]; } else { [coder encodeObject: _substrate]; [coder encodeValueOfObjCType: @encode(double) at: &_beginT]; } return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if ([coder allowsKeyedCoding]) { _substrate = RETAIN([coder decodeObjectForKey: @"FOOMReadTranspSnd:substrate"]); _beginT = [coder decodeDoubleForKey: @"FOOMReadTranspSnd:beginT"]; } else { _substrate = RETAIN([coder decodeObject]); [coder decodeValueOfObjCType: @encode(double) at: &_beginT]; } _samples = NULL; return self; } @end --- NEW FILE: FOOMDiv.h --- /* -*-Mode:objc-*- */ /* * FOOMDiv.h * * module dic * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMDiv.h,v 1.1 2007/12/14 14:16:10 rumori Exp $ */ #ifndef FOOM_FOOMDIV_H_INCLUDED #define FOOM_FOOMDIV_H_INCLUDED #include <FOO/FOOModule.h> @interface FOOMDiv : FOOModule <NSCoding> { } @end #endif /* #ifndef FOOM_FOOMDIV_H_INCLUDED */ --- NEW FILE: FOOMTransposeSnd.h --- /* -*-Mode:objc-*- */ /* * FOOMTransposeSnd.h * * module transp-snd * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMTransposeSnd.h,v 1.1 2007/12/14 14:16:16 rumori Exp $ */ #ifndef FOOM_FOOMTRANSPOSESND_H_INCLUDED #define FOOM_FOOMTRANSPOSESND_H_INCLUDED #include <FOO/FOOEagerModule.h> #include <FOO/FOOSoundStream.h> #include <FOO/FOOSoundFile.h> #include <FOO/FOORegion.h> #include <FOO/FOOLookupTable.h> #include "FOOMMath.h" @interface FOOMTransposeSnd : FOOEagerModule <NSCoding> { /* Substrate *substrate; /\* input *\/ */ id _substrate; sample_t *_samples; /* cache */ int _offset; /* cache's sample position in input */ int _count; /* size of cache */ int _end; /* end of cache */ int _taps; /* # of zero-crossings in sinc used for resampling */ FOOLookupTable *_table; /* sinc */ int _begin; /* begin time */ double _position; /* sample position in input */ double _beginT; /* begin time in seconds */ double _factor; /* sampling rate correction */ } - initializeWith: substr taps: (int)n; - initPos; @end #endif /* #ifndef FOOM_FOOMTRANSPOSESND_H_INCLUDED */ --- NEW FILE: FOOMReverb.m --- /* -*-Mode:objc-*- */ /* * FOOMReverb.m * * module reverb * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMReverb.m,v 1.1 2007/12/14 14:16:15 rumori Exp $ */ //#include <stdlib.h> /* needed ? [GE] */ #include "FOOMReverb.h" /************************** begin reverb code in C ***************************/ #define fcopy(s, d, c) bcopy(s, d, (c) * sizeof(float)) /* * default delay times */ static float delay_times_8[] = { .05113, .05371, .05741, .06017, .06654, .07267, .07591, .08107 }; static float delay_times_12[] = { .05113, .05371, .05741, .06017, .06654, .07267, .07591, .08107, .08465, .09215, .09789, .10511 }; static float delay_times_16[] = { .04113, .04371, .04741, .05017, .05654, .06267, .06591, .06807, .07167, .07301, .07789, .08011, .08222, .08501, .08777, .08777 }; /* * _filters */ static filter_t* make_filter(double len, double tr0, double damp) { filter_t *new; if ((new = (filter_t*)malloc(sizeof(filter_t))) == NULL) { return NULL; } if (tr0 == -1) { new->c0 = 1; damp = 1; } else { new->c0 = pow(10., -3 * len / tr0); } new->d0 = 2. / (1 + pow(new->c0, 1 - 1 / damp)); new->c1 = 1 - new->d0; new->z_1 = 0; return new; } static filter_t** make_filters(int n, double tr0, double damp, float *delays) { filter_t **new; int i; if ((new = (filter_t**)malloc(n * sizeof(filter_t*))) == NULL) { return NULL; } if (delays == NULL) { switch (n) { case 8: delays = delay_times_8; break; case 12: delays = delay_times_12; break; case 16: delays = delay_times_16; break; default: return NULL; } for (i = 0; i < n; i++) { new[i] = make_filter(delays[i], tr0, damp); } } return new; } static void free_filters(filter_t **filters, int n) { int i; for (i = 0; i < n; i++) { free(filters[i]); } free(filters); } /* * delays */ static delay_t* make_delay(int len, int bufsiz) { delay_t *new; float *p; int i; if (len < bufsiz) { len = bufsiz; } if ((new = (delay_t*)malloc(sizeof(delay_t)+sizeof(float)*len)) == NULL) { return NULL; } new->begin = (float*) (new + 1); new->end = new->begin + len; new->read = new->begin; new->write = new->end - bufsiz; for (i = 0, p = new->begin; i < len - bufsiz; i++) { *p++ = 0; } return new; } static delay_t** makedelays(int n, int bufsiz, double sr, float* delays) { delay_t **new; int i, len; if ((new = (delay_t**)malloc(n * sizeof(delay_t*))) == NULL) { return NULL; } if (delays == NULL) { switch (n) { case 8: delays = delay_times_8; break; case 12: delays = delay_times_12; break; case 16: delays = delay_times_16; break; default: return NULL; } } for (i = 0; i < n; i++) { len = rint(delays[i] * sr); new[i] = make_delay(len, bufsiz); } return new; } static void freedelays(delay_t **delays, int n) { int i; for (i = 0; i < n; i++) { free(delays[i]); } free(delays); } /* * delay write */ static void delwrite(int j, delay_t** d, float** s, int l) { int i, n, m; delay_t *delay; float *data; for (i = 0; i < j; i++) { delay = d[i]; data = s[i]; if (delay->write + l <= delay->end) { fcopy(data, delay->write, l); delay->write += l; } else { n = delay->end - delay->write; m = l - n; fcopy(data, delay->write, n); fcopy(data + n, delay->begin, m); delay->write = delay->begin + m; } if (delay->write >= delay->end) { delay->write = delay->begin; } } } /* * delay read and filter */ static void ab1delay(int n, delay_t** d, filter_t** f, float** s, int l, double x) { int i, j; double z_1, c0, c1, d0; delay_t *delay; filter_t *filter; float *data, *p, *e; for (i = 0; i < n; i++) { delay = d[i]; filter = f[i]; data = s[i]; z_1 = filter->z_1; c0 = filter->c0; c1 = filter->c1; d0 = filter->d0; p = delay->read; e = delay->end; for (j = 0; j < l; j++) { z_1 = c0 * *p++ + c1 * z_1; *data++ = d0 * z_1 * x; if (p >= e) { p = delay->begin; } } delay->read = p; filter->z_1 = z_1; } } /* * matrices */ static void hada8(float **d, int n) { float *x0 = d[0], *x1 = d[1], *x2 = d[2], *x3 = d[3]; float *x4 = d[4], *x5 = d[5], *x6 = d[6], *x7 = d[7]; register float t0, t1, t2, t3, t4, t5; register float t6, t7, t8, t9, ta, tb; while (n--) { t4 = *x0 + *x1; t5 = *x0 - *x1; t6 = *x2 + *x3; t7 = *x2 - *x3; t0 = t4 + t6; t1 = t5 + t7; t2 = t4 - t6; t3 = t5 - t7; t4 = *x4 + *x5; t5 = *x4 - *x5; t6 = *x6 + *x7; t7 = *x6 - *x7; t8 = t4 + t6; t9 = t5 + t7; ta = t4 - t6; tb = t5 - t7; *x0++ = t0 + t8; *x1++ = t1 + t9; *x2++ = t2 + ta; *x3++ = t3 + tb; *x4++ = t0 - t8; *x5++ = t1 - t9; *x6++ = t2 - ta; *x7++ = t3 - tb; } } static void feedback3(float **x, int n) { float *x0 = x[0], *x1 = x[1], *x2 = x[2]; float t; while (n--) { t = (*x0 + *x1 + *x2) * -2/3.; *x0++ += t; *x1++ += t; *x2++ += t; } } #define f4(x, i0, i1, i2, i3, o0, o1, o2, o3) \ x = (*i0 + *i1 + *i2 + *i3) * -.5; \ o0 = *i0++ + x; \ o1 = *i1++ + x; \ o2 = *i2++ + x; \ o3 = *i3++ + x; static void feedback4(float **x, int n) { float *x0 = x[11], *x1 = x[2], *x2 = x[5]; float *x3 = x[8], *x4 = x[9], *x5 = x[0]; float *x6 = x[3], *x7 = x[6], *x8 = x[10]; float *x9 = x[1], *xa = x[4], *xb = x[7]; float *y0 = x[0], *y1 = x[1], *y2 = x[2]; float *y3 = x[3], *y4 = x[4], *y5 = x[5]; float *y6 = x[6], *y7 = x[7], *y8 = x[8]; float *y9 = x[9], *ya = x[10], *yb = x[11]; float t, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb; while (n--) { f4(t, x0, x1, x2, x3, t0, t1, t2, t3); f4(t, x4, x5, x6, x7, t4, t5, t6, t7); f4(t, x8, x9, xa, xb, t8, t9, ta, tb); *y0++ = t0; *y1++ = t1; *y2++ = t2; *y3++ = t3; *y4++ = t4; *y5++ = t5; *y6++ = t6; *y7++ = t7; *y8++ = t8; *y9++ = t9; *ya++ = ta; *yb++ = tb; } } static void feedback12(float **x, int n) { feedback3(x, n); feedback3(x + 3, n); feedback3(x + 6, n); feedback3(x + 9, n); feedback4(x, n); } static void hada16(float **d, int n) { hada8(d, n); hada8(d + 8, n); { float *x0 = d[0], *x1 = d[1], *x2 = d[2], *x3 = d[3]; float *x4 = d[4], *x5 = d[5], *x6 = d[6], *x7 = d[7]; float *x8 = d[8], *x9 = d[9], *x10 = d[10], *x11 = d[11]; float *x12 = d[12], *x13 = d[13], *x14 = d[14], *x15 = d[15]; float t; while (n--) { t = *x8; *x8++ = *x0 - t; *x0++ += t; t = *x9; *x9++ = *x1 - t; *x1++ += t; t = *x10; *x10++ = *x2 - t; *x2++ += t; t = *x11; *x11++ = *x3 - t; *x3++ += t; t = *x12; *x12++ = *x4 - t; *x4++ += t; t = *x13; *x13++ = *x5 - t; *x5++ += t; t = *x14; *x14++ = *x6 - t; *x6++ += t; t = *x15; *x15++ = *x7 - t; *x7++ += t; } } } /*************************** end reverb code in C ****************************/ #define INFINITE_TAIL 2147483647 // 2^31-1 samples => ~12 hours at 50 kHz @implementation FOOMReverb - initializeChannels: (int)n tr0: (double)t damp: (double)d delays: (float*)l { int i; if (n != 8 && n != 12 && n != 16) { FOO_ERROR(YES, self); } _channels = n; _tr0 = t; _damp = d; _delays = NULL; if (l != NULL) { for (i = 0; i < _channels; i++) { _delvec[i]= l[i]; } _times = _delvec; } else { _times = NULL; } _filters = make_filters(_channels, _tr0, _damp, _times); return self; } - reset { [super reset]; if (_buffers != nil) { RELEASE(_buffers); _buffers = nil; } // reset delays and _filters here return self; } - (void) dealloc { if (_buffers != nil) { RELEASE(_buffers); _buffers = nil; } if (_outputs != nil) { RELEASE(_outputs); _outputs = nil; } if (_delays != NULL) { freedelays(_delays, _channels); } if (_filters != NULL) { free_filters(_filters, _channels); } [super dealloc]; } - assignBuffers: (int)currBuffer { int i; id m; [super assignBuffers:currBuffer]; if (_buffers == nil) { _buffers = [[NSMutableArray allocWithZone:[self zone]] init]; _outputs = [[NSMutableArray allocWithZone:[self zone]] init]; for (i = 0; i < _channels; i++) { [_buffers addObject: [_context nextSharedBuffer]]; [_outputs addObject: [_context nextSharedBuffer]]; } } return self; } - (BOOL)activate { int i; _active = NO; if ([_inputs count] == 0) { return _active; } #if 0 for (i = 0; i < [inputs count]; i++) { if ([[inputs objectAt:i] activate] == YES) { // if ([[inputs objectAtIndex:i] activate] == YES) { _tail = INFINITE_TAIL; return (_active = YES); } } if (_tail > 0) { if (_tail == INFINITE_TAIL) _tail = INFINITE_TAIL; // calculate tail here, now infinite ! else _tail -= BLOCKSIZE; _active = YES; } else { _active = NO; } #else for (i = 0; i < [_inputs count]; i++) { [INPUT(i) activate]; } _active = YES; #endif return _active; } - (BOOL)compute { int i, n = BLOCKSIZE; float *data[16]; id m; if (_active == YES) { if (_valid == YES) { return _active; } if (_delays == NULL) { _delays = makedelays(_channels, n, SAMPLERATE, _times); } for (i = 0; i < _channels; i++) { data[i] = [[_buffers objectAtIndex: i] data]; } delwrite(_channels, _delays, data, n); switch (_channels) { case 8: ab1delay(_channels, _delays, _filters, data, n, 0.353553); hada8(data, n); break; case 12: ab1delay(_channels, _delays, _filters, data, n, 1.); feedback12(data, n); break; case 16: ab1delay(_channels, _delays, _filters, data, n, 0.25); hada16(data, n); break; default: FOO_ERROR(NO, NO); } for (i = 0; i < _channels; i++) { [[_outputs objectAtIndex: i] mov: [_buffers objectAtIndex: i]]; } for (i = 0; i < INPUTS; i++) { m = INPUT(i); [m compute]; [[_buffers objectAtIndex: i] add: [m getBuffer]]; } [_buffer mov: [_outputs objectAtIndex: 0]]; _valid = YES; } else { memset([_buffer data], 0, sizeof(sample_t) * BLOCKSIZE); for (i = 0; i < _channels - 1; i++) { memset([[_buffers objectAtIndex: i] data], 0, sizeof(sample_t) * BLOCKSIZE); } } return _active; } - getBuffer: (int)index { if (index < 0 || index >= _channels) { FOO_ERROR(YES, nil); } return [_outputs objectAtIndex: index]; } - (int)channels { return _channels; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeInt: _channels forKey: @"FOOMReverb:channels"]; [coder encodeDouble: _tr0 forKey: @"FOOMReverb:tr0"]; [coder encodeDouble: _damp forKey: @"FOOMReverb:damp"]; } else { [coder encodeValueOfObjCType: @encode(int) at: &_channels]; [coder encodeValueOfObjCType: @encode(double) at: &_tr0]; [coder encodeValueOfObjCType: @encode(double) at: &_damp]; } return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if ([coder allowsKeyedCoding]) { _channels = [coder decodeIntForKey: @"FOOMReverb:channels"]; _tr0 = [coder decodeDoubleForKey: @"FOOMReverb:tr0"]; _damp = [coder decodeDoubleForKey: @"FOOMReverb:damp"]; } else { [coder decodeValueOfObjCType: @encode(int) at: &_channels]; [coder decodeValueOfObjCType: @encode(double) at: &_tr0]; [coder decodeValueOfObjCType: @encode(double) at: &_damp]; } return self; } @end --- NEW FILE: FOOMComb.m --- /* -*-Mode:objc-*- */ /* * FOOMComb.m * * feedback delay line * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMComb.m,v 1.1 2007/12/14 14:16:08 rumori Exp $ */ #include "FOOMComb.h" @implementation FOOMComb - (id) initWithTaps: (int)taps maxDelay: (double)maxDelay { _taps = taps; _table = [FOOGlobalsManager getSineXoverXTable: _taps]; _line = NULL; _maxDelayT = maxDelay; return self; } - (void) dealloc { NSZoneFree([self zone], _line); _line = NULL; [super dealloc]; } - reset { [super reset]; if (_line) { NSZoneFree([self zone], _line); _line = NULL; } _ptr = 0; return self; } - startUp { [super startUp]; _maxDelay = SEC_TO_SAM(_maxDelayT); _line = NSZoneCalloc([self zone], _maxDelay, sizeof(sample_t)); _ptr = 0; return self; } - (BOOL) activate { // if (INPUTS < 2 || [INPUT(0) activate] == NO || [INPUT(1) activate] == NO) // { // _active = NO; // } // else // { // _active = YES; // } // take feedback in account [INPUT(0) activate]; [INPUT(1) activate]; [INPUT(2) activate]; return (_active = YES); } - (BOOL) compute { FOOModule *m0, *m1, *m2; sample_t *input, *delay, *feedback, *output; int i, n, dpos, ipos; double tap, sr, fpos, fti, tdelta; int tot, tinc, ti1, ti2; // total of taps, tap increment sample_t *base, *delta; // lookup table, delta table COMPUTE_PROLOGUE; m0 = INPUT(0); m1 = INPUT(1); m2 = INPUT(2); [m0 compute]; [m1 compute]; [m2 compute]; input = DATA_OF_MOD(m0); delay = DATA_OF_MOD(m1); feedback = DATA_OF_MOD(m2); output = DATA_OF_BUF(_buffer); n = BLOCKSIZE; sr = SAMPLERATE; tot = _taps / 2; tinc = [_table getSize] / tot; base = [_table getBase]; delta = [_table getDelta]; while (n--) { // interpolate tap = 0; fpos = *delay++ * sr; ipos = (int)fpos; // shorter delay than samples for interpolation? if (ipos < tot) { FOO_ERROR(NO, YES); ipos = tot; } fti = (fpos - ipos) * tinc; ti1 = (int)fti; ti2 = tinc - ti1 - 1; tdelta = fti - ti1; dpos = _ptr + ipos; while (dpos > _maxDelay - 1) { // wrap around dpos -= _maxDelay; } for (i = tot; i > 0; --i, ti1 += tinc) { tap += _line[dpos--] * (base[ti1] + delta[ti1] * tdelta); if (dpos < 0) { dpos = _maxDelay - 1; } } tdelta = 1 - tdelta; dpos = _ptr + ipos + 1; while (dpos > _maxDelay - 1) { // wrap around dpos -= _maxDelay; } for (i = tot; i > 0; --i, ti2 += tinc) { tap += _line[dpos++] * (base[ti2] + delta[ti2] * tdelta); if (dpos > _maxDelay - 1) { dpos = 0; } } // copy + feedback to delay line _line[_ptr] = tap * *feedback++ + *input; --_ptr; if (_ptr < 0) { // wrap around _ptr = _maxDelay - 1; } // output *output++ = tap; } COMPUTE_EPILOGUE; } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; return self; } @end --- NEW FILE: FOOMInteg.h --- /* -*-Mode:objc-*- */ /* * FOOMInteg.h * * module integ * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMInteg.h,v 1.1 2007/12/14 14:16:12 rumori Exp $ */ #ifndef FOOM_FOOMINTEG_H_INCLUDED #define FOOM_FOOMINTEG_H_INCLUDED #include <FOO/FOOModule.h> @interface FOOMInteg : FOOModule <NSCoding> { double _last; } @end #endif /* #ifndef FOOM_FOOMINTEG_H_INCLUDED */ --- NEW FILE: FOOMLine.m --- /* -*-Mode:objc-*- */ /* * FOOMLine.m * * module line * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMLine.m,v 1.1 2007/12/14 14:16:12 rumori Exp $ */ #include "FOOMLine.h" @implementation FOOMLine - initializeStart: (double)s end: (double)e dur: (double)d { _beginT = TIMEFRAME; _endT = _beginT + d; _origin = s; _phase = 0; _range = e - s; return self; } - reset { [super reset]; _phase = -_incr; return self; } - startUp { [super startUp]; _begin = SEC_TO_SAM(_beginT); _end = SEC_TO_SAM(_endT); _incr = _range / (_end - _begin); _phase = -_incr; return self; } - (BOOL) activate { if (_begin >= BLOCKEND || _end < SAMPLETIME) { _active = NO; } else { _active = YES; } return _active; } - (BOOL) compute { sample_t *p; double c, i, o; int b, e, s, m; COMPUTE_PROLOGUE; p = DATA_OF_BUF(_buffer); if (_begin > SAMPLETIME) { b = _begin - SAMPLETIME; memset(p, 0, b * sizeof(sample_t)); } else { b = 0; } if (_end < BLOCKEND) { e = BLOCKSIZE - (BLOCKEND - _end); memset(p + e, 0, (BLOCKSIZE - e) * sizeof(sample_t)); } else { e = BLOCKSIZE; } s = e - b; p += b; o = _origin; i = _incr; c = _phase; m = s; while (m--) { c += i; *p++ = o + c; } _phase = c; COMPUTE_EPILOGUE; } - (int) getTimeInterval: (double*)b : (double*)e { *b = _beginT; *e = _endT; return (TI_BEG_END); } /* * archiving methods */ - (void) encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; if ([coder allowsKeyedCoding]) { [coder encodeDouble: _origin forKey: @"FOOMLine:origin"]; [coder encodeDouble: _incr forKey: @"FOOMLine:incr"]; [coder encodeDouble: _beginT forKey: @"FOOMLine:beginT"]; [coder encodeDouble: _endT forKey: @"FOOMLine:endT"]; [coder encodeDouble: _range forKey: @"FOOMLine:range"]; } else { [coder encodeValueOfObjCType: @encode(double) at: &_origin]; [coder encodeValueOfObjCType: @encode(double) at: &_incr]; [coder encodeValueOfObjCType: @encode(double) at: &_beginT]; [coder encodeValueOfObjCType: @encode(double) at: &_endT]; [coder encodeValueOfObjCType: @encode(double) at: &_range]; } return; } - (id) initWithCoder: (NSCoder *)coder { self = [super initWithCoder: coder]; if ([coder allowsKeyedCoding]) { _origin = [coder decodeDoubleForKey: @"FOOMLine:origin"]; _incr = [coder decodeDoubleForKey: @"FOOMLine:incr"]; _beginT = [coder decodeDoubleForKey: @"FOOMLine:beginT"]; _endT = [coder decodeDoubleForKey: @"FOOMLine:endT"]; _range = [coder decodeDoubleForKey: @"FOOMLine:range"]; } else { [coder decodeValueOfObjCType: @encode(double) at: &_origin]; [coder decodeValueOfObjCType: @encode(double) at: &_incr]; [coder decodeValueOfObjCType: @encode(double) at: &_beginT]; [coder decodeValueOfObjCType: @encode(double) at: &_endT]; [coder decodeValueOfObjCType: @encode(double) at: &_range]; } return self; } @end --- NEW FILE: FOOMComb.h --- /* -*-Mode:objc-*- */ /* * FOOMComb.h * * feedback delay line * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMComb.h,v 1.1 2007/12/14 14:16:08 rumori Exp $ */ #ifndef FOOM_FOOMCOMB_H_INCLUDED #define FOOM_FOOMCOMB_H_INCLUDED #include <FOO/FOOModule.h> #include <FOO/FOOLookupTable.h> @interface FOOMComb : FOOModule <NSCoding> { int _maxDelay; // maximum delay in samples = size of delay line double _maxDelayT; // maximum delay in seconds sample_t *_line; // delay line int _ptr; // write index in delay line int _taps; // num of taps for resampling FOOLookupTable *_table; // sinc table for resampling } - (id) initWithTaps: (int)taps maxDelay: (double)maxDelay; @end #endif /* #ifndef FOOM_FOOMALLPASS_H_INCLUDED */ --- NEW FILE: FOOMReverb.h --- /* -*-Mode:objc-*- */ /* * FOOMReverb.h * * module reverb * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo 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. * * foo 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 foo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: FOOMReverb.h,v 1.1 2007/12/14 14:16:15 rumori Exp $ */ #ifndef FOOM_FOOMREVERB_H_INCLUDED #define FOOM_FOOMREVERB_H_INCLUDED #include <FOO/FOOEagerModule.h> #include <Foundation/NSArray.h> #include <math.h> typedef struct _delay { float *begin; float *end; float *read; float *write; } delay_t; typedef struct _filter { double c0; double c1; double d0; double z_1; } filter_t; @interface FOOMReverb : FOOEagerModule <NSCoding> { NSMutableArray *_buffers; // statically typed NSMutableArray *_outputs; // statically typed delay_t **_delays; filter_t **_filters; int _channels; double _tr0; double _damp; int _tail; float _delvec[16]; float *_times; } - initializeChannels: (int)n tr0: (double)t damp: (double)d delays: (float*)l; - getBuffer: (int)count; - (int) channels; @end #endif /* #ifndef FOOM_FOOMREVERB_H_INCLUDED */ --- NEW FILE: FOOMReadBpf.m --- /* -*-Mode:objc-*- */ /* * FOOMReadBpf.m * * module read bpf * */ /* * foo sound synthesis system * * (C) 1993-2005 Gerhard Eckel, Ramon Gonzalez-Arroyo * (C) 2003-2005 Martin Rumori * (C) 1993-1996 IRCAM, ZKM */ /* * This file is part of foo. * * foo is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as... [truncated message content] |