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,