gusucode.com > 声音的处理有:LPC,FFT,共振峰,频谱源码程序 > siganlandsystemusingMatlab/SSUM/library/additive.m

    function signal = additive(num_samples, frequency, freq_skew, ...
		amplitude, freq_env, amp_env, partials, Fs)
%ADDITIVE Additive synthesis algorithm
%   ADDITIVE(NUM_SAMPLES, FREQUENCY, FREQ_SKEW, AMPLITUDE, FREQ_ENV, AMP_ENV,
%   PARTIALS, FS) synthesizes a signal using separate envelopes for FREQUENCY
%   and AMPLITUDE of a single sinusoid for NUM_SAMPLES. The sinusoid's
%   FREQUENCY is scaled by FREQ_ENV (between 0 - 1) proportional to FREQ_SKEW.
%   AMPLITUDE remains in the domain 0 - 1, even when scaled by AMP_ENV.
%
%   Example: 
%   Todo: employ varargin
%
%   Author(s): Bob L. Sturm, 20030701-03
%   Copyright 2003 University of California, Santa Barbara
%   $Revision: 1.20 $  $Date: 2002/03/28 17:31:26 $

	partials = partials{:};
	num_partials = size(partials,2)/2;
	% Create envelopes
	freq_envelope = zeros(1,num_samples);
	amp_envelope = zeros(1,num_samples);

	% Populate envelopes
	segment = [0 0];
	value = [0 0];
	amp_env = amp_env{:};
	for i=1:length(amp_env)/2-1,
		segment(1) = floor(amp_env(2*i-1)*num_samples+1);		% Start
		segment(2) = floor(amp_env(2*i+1)*num_samples);		% End
		value(1) = amp_env(2*i);
		value(2) = amp_env(2*(i+1));
		amp_envelope(segment(1):segment(2)) = amplitude*...
			linspace(value(1),value(2),segment(2)-segment(1)+1);
	end
	%figure
	%plot(linspace(0,1,num_samples),amp_envelope);

	segment = [0 0];
	value = [0 0];
	freq_env = freq_env{:};
	for i=1:length(freq_env)/2-1,
		segment(1) = floor(freq_env(2*i-1)*num_samples+1);		% Start
		segment(2) = floor(freq_env(2*i+1)*num_samples);		% End
		value(1) = freq_env(2*i)*freq_skew;
		value(2) = freq_env(2*(i+1))*freq_skew;
		freq_envelope(segment(1):segment(2)) = ...
			linspace(value(1),value(2),segment(2)-segment(1)+1);
	end
	%figure
	%plot(linspace(0,1,num_samples),freq_envelope)

	% Create signal
	signal = zeros(1,num_samples);
	for i=1:num_partials,
		freq(i) = 0;
	end

	for i=1:num_samples,
		for j=1:num_partials,
			% Integrate frequency function
			freq(j) = freq(j) + (freq_envelope(i)+frequency*partials(2*j-1))/Fs;
			signal(i) = signal(i) + ...
				partials(2*j)*amp_envelope(i).*sin(2*pi*freq(j));
		end
	end

% HISTORY
% Modified from original Common Lisp Music (CLM) code, from CCRMA, Stanford.
%(definstrument bird 
%	(startime dur frequency freq-skew amplitude freq-envelope amp-envelope)
%	(multiple-value-bind (beg end) (times->samples startime dur)
%		(let* ((amp-env (make-env amp-envelope amplitude dur))
%			(gls-env (make-env freq-envelope (hz->radians freq-skew) dur))
%			(s (make-oscil :frequency frequency)))
%			(run (loop for i from beg to end do
%				(* (env amp-env) (oscil s (env gls-env))))))))
%
% So this defines an instrument (function) called bird which takes as required
% arguments:
% 			startime, dur, frequency, freq-skew, 
%			amplitude, freq-envelope, amp-envelope,
%(definstrument bigbird 
%	(start dur frequency freqskew amplitude freq-envelope amp-envelope partials)
%	(multiple-value-bind (beg end) (times->samples start dur)
%		(let* ((gls-env (make-env freq-envelope (hz->radians freqskew) dur))
%			(os (make-oscil :frequency frequency))
%			(coeffs (partials->polynomial (normalize-partials partials)))
%			(amp-env (make-env amp-envelope amplitude dur)))
%			(run (loop for i from beg to end do
%				(* (env amp-env) (polynomial coeffs (oscil os (env gls-env)))))))))

% So this defines another instrument called bigbird which takes as required
% arguments:
% 			startime, dur, frequency, freq-skew, 
%			amplitude, freq-envelope, amp-envelope, partials,