next Index
previous Conclusions
up Nonlinear Commuted Synthesis of Bowed Strings   Contents   Global Contents
global_index Global Index   Index   Search

Appendix: Selected Software Items

All simulations for this paper were carried out using Perry Cook's Synthesis ToolKit (STK) in C++ [2]. The method stringVelocityAtPosition(int position) below can be added to bowed.cpp in the STK to facilitate extracting the string state for display as shown in Fig. 6. (Animations of bowed-string motion using this added method were found to be especially valuable for obtaining insight into bowed string dynamics.)

MY_FLOAT BowedStr :: stringVelocityAtPosition(int p) /* p from 0 to nsamples-1 */
{
    int bdelrt = (int)bridgeDelay->delay()+1; /* bow-to-bridge-to-bow + p.l. delay */
    int ndelrt = (int)neckDelay->delay()+1; /* bow-to-nut-to-bow + p.l. delay */
    int bdel = bdelrt >> 1; /* number of spatial samples from bridge to bow */
    int ndx = bdel - p; /* convert (0:N-1) position to delay (1:N) on left */
    MY_FLOAT leftGoingAtP;
    MY_FLOAT rightGoingAtP;
    if (p < bdel) {
        /* "Now" is always where the InPoint points which is not yet written */
        /* OutPoint points to "now - delay" */
        /* Bridge is on the left, nut on the right */
        /* "Now" is at the bow */
        /* Position zero is at far left = half way along delay line */
        leftGoingAtP = bridgeDelay->contentsAtNowMinus(ndx);
        int rndx = bdelrt-ndx+1;
        if (rndx < bdelrt) { /* last sample delay resides in lastOutput variable */
            rightGoingAtP = -bridgeDelay->contentsAtNowMinus(rndx);
        } else {
            rightGoingAtP = -bridgeDelay->lastOut();
        }
    } else { /* nut side */
        ndx = p - bdel + 1; /* convert (0:N-1) position to delay (1:N) */
        rightGoingAtP = neckDelay->contentsAtNowMinus(ndx);
        int lndx = ndelrt-ndx+1;
        if (lndx < ndelrt) {
            leftGoingAtP = -neckDelay->contentsAtNowMinus(lndx);
        } else {
            leftGoingAtP = -neckDelay->lastOut();
        }
    }
    return rightGoingAtP + leftGoingAtP;
}

Usage of the above method is illustrated in the following code fragment:

    MY_FLOAT stringState[MAXPERIOD];
    for (i=0;i<period/2;i++)    
        stringState[i] = 0;
    for (i=0;i<samples;i++) { /* main sample loop */
        ...
        if (i<20*period) {
            MY_FLOAT v = 0.0;
            long len = period/2;
            for (int j=0; j<len; j++) {
                v = vscale*vln->stringVelocityAtPosition(j); /* m/s */
                stringState[j] += v*ONE_OVER_SRATE; /* m */
                stringOut->tick(STRINGSCALING*stringState[j]); /* to soundfile */
            }
        }

The following matlab function was used to generate highly helpful animations of the string state. Each string snapshot was written successively into one long sound file, and this routine was called with the sound data along with M set to the snapshot length in samples:

function out=datamovie(in,M,sleep,ax);
%DATAMOVIE   datamovie(in,M,sleep,ax);
%           Display sequence of data frames of length M.
%           If sleep>0, that many cycles are waited between plots.
%           If sleep == -1, RETURN is needed to advance to the next plot.
%           If ax is a quoted string, "axis(ax)" is called.
clf;
if (nargin<2), M=length(in); end
if (nargin<3), sleep=0; end
if (nargin<4), ax = [1 M min(in) 1.1*max(in)]; end
skip = M; h=plot(in(1:M),'erasemode','background'); axis(ax); drawnow;
if sleep == -1, disp '*** PAUSING *** RETURN to continue'; pause; end
for i=1:(length(in)-M)/skip
    set(h,'ydata',in(skip*i+1:skip*i+M));
    if sleep == -1, disp '*** PAUSING *** RETURN to continue'; pause;
    elseif sleep>0, for j=1:sleep, y = tan(j); end; end
end

Usage of the datamovie function is illustrated by the matlab script below:

% seestr.m - matlab script for viewing bowed string waveshape evolution
ilen = 50;              % Number of spatial samples along string
sleep = 0;              % pause/speed control to datamovie
name1 = 'string'; [strdata fs len header] = loadsig(name1); % for NeXT .snd files
strdata = strdata/32768.0;
datamovie(strdata,ilen,sleep);


next Index
previous Conclusions
up Nonlinear Commuted Synthesis of Bowed Strings   Contents   Global Contents
global_index Global Index   Index   Search

``Nonlinear Commuted Synthesis of Bowed Strings'', by Julius O. Smith III, Proceedings of the International Computer Music Conference (ICMC-97, Thessaloniki), Computer Music Association, 1997..

Download PDF version (ncbs.pdf)
Download compressed PostScript version (ncbs.ps.gz)

(Browser settings for best viewing results)

Copyright © 2004-09-02 by Julius O. Smith III
Center for Computer Research in Music and Acoustics (CCRMA),   Stanford University
CCRMA  (automatic links disclaimer)