% maraca.m

fs = 44100;
T = 1 / fs;
N = 1 * fs;
nBeans = 4;
shellF = 3200.0;
shellR = 0.96;
systemDecay = 0.999;
soundDecay = 0.95;
y = zeros(1, N);

Ns = 0.05 * fs;
shakeEnergy = 1.0 - cos(2*pi*[0:Ns-1]/Ns);
shakeEnergy = [ shakeEnergy zeros(1, 5050 - Ns) ];

gain = log( nBeans ) / (log( 4.0 ) * 40.0 * nBeans);

b = [1 -1];
a = [1 -2 * shellR * cos( 2 * pi * shellF * T ) shellR^2];

sndLevel = 0;
z = [0 0];
k = 1;

for n = 1:N,
  
  e = shakeEnergy( k ) * systemDecay;
  if ( rand(1) * 1024 < nBeans )
    sndLevel = sndLevel + (gain * e);
    x = sndLevel;
  else
    x = 0;
  end

  % If the following line is commented out, each "event" sound is
  % generated as the impulse response of the resonance filter.  Otherwise,
  % the resonance filter is fed enveloped noise.
  %x = sndLevel * (2 * rand(1) - 1.0);
  [y(n) z] = filter( [1 -1], a, x, z );
  
  sndLevel = sndLevel * soundDecay;
  k = k + 1;
  if ( k > 4050 ) k = 1; end
  
end

ynorm = 0.95 * y / max(abs(y));
sound( ynorm, fs );