Old BuzzDev Answers

From Jeskola Buzz Wiki
Revision as of 14:28, 26 July 2009 by Zephod (Talk | contribs)

Jump to: navigation, search


Answers by Oskari:

Date: Fri, 12 Jun 1998 20:12:27 +0300 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: wavetable 

At 11:31 AM 6/11/98 -0500, you wrote:
>is it possible for a plug-in to access the samples in the wavetable?

Yep, Jeskola Tracker wouldn't work otherwise (it's just like any other
machine). You can also write to the wavetable if you want to write a
nonrealtime samplegenerator or something like that.

virtual CWaveInfo const *GetWave(int const i);
virtual CWaveLevel const *GetWaveLevel(int const i, int const level);
virtual int GetFreeWave();
virtual bool AllocateWave(int const i, int const size, char const *name);
virtual CWaveLevel const *GetNearestWaveLevel(int const i, int const note);

In tracker you just need to do this:

CWaveInfo const *pWave = pCB->GetWave(pstate->iWave);
CWaveLevel const *pLevel = pCB->GetNearestWaveLevel(pstate->iWave,

See the attached file for example of writing to wavetable. It's the MOD
importer code of the Tracker.

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com


Date: Tue, 16 Jun 1998 03:18:37 +0300 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: importing .IT file samples 

At 04:32 PM 6/14/98 -0500, you wrote:
>Currently it is messy - you add the machine, and the mi::Init() method pops
>open a file dialog to select the .IT file to load samples from.  In the
>a mutex lock error message box pops up.

You shouldn't show any dialogs in Init(). 

>What would be the correct way to implement something like this which isn't
>a generator or effect?
>I was thinking the context menu of the machine should have an "Import..."
>command, just like the Tracker machine does.   How do I do that, if possible?

Yep, just implement the Command() method:

void mi::Command(int const i)
        case 0: ImportModule(); break;
        case 1: AnotherCommand(); break;

And change last line of MacInfo to "Import Module...\nAnother command"

Note that you must lock the machines if you are changing something that the
player thread is using at the same time. The easiest and safest way to do
is to use the MACHINE_LOCK macro like this:

    MACHINE_LOCK   // this constructs a C++ object

    // do something..

} // <- unlock happens here

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com


Date: Wed, 17 Jun 1998 07:03:05 +0100 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: simple buzz tracker question 

At 04:55 PM 6/16/98 +0200, you wrote:
>im trying to code a simple buzz tracker. for now it plays samples nicely
>at their default rate.  How do i calculate the playback rate according to
>the entered notes and resample the samples to this rate in the generator
>code ??  Are there some build-in functions to do this ?

Rate = 2.0 ^ (N / 12.0)

Where N is the note relative to the root note. For example if root note is
C-4 then N=1 would be C#4 and N=-12 would be C-3.

dsplib provides a resampler function, so you should use it (see resample.h
for help). The resampler has separate inner loops for all special cases so
it's very efficient.

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com


Date: Fri, 26 Mar 1999 03:36:33 +0200 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: New machine released: JoyPlug 1 

At 06:35 PM 3/25/99 -0600, you wrote:
>JoyPlug 1 has been released!
>JoyPlug 1 is a joystick-controlled lowpass resonant filter with 
>distortion.  Instead of preprogramming in your filter data, just 
>control it with the joystick, live.  The source code is included as a 
>slightly more complicated example of how to write something in Buzz.
>The plugin works with Buzz 1.x and a Win95 compatable joystick (3 
>axis joystick preffered)

Sounds like a cool machine. I wish I had Win95 and a joystick. :)
The documentation was very nice too but there were some wrong information.
Here are some corrections so that people don't get confused. 

If there are functions that you don't need (like SetnumTracks and Tick in
your machine) you don't need to implement them either.

The range of the signal is -32768..32767 inclusive if you want full dynamic
range without lowering the master volume. It's not limited to that however.
Machines can use much larger values if they need to but the user must
manually lower the amps to avoid clipping.

Those were both just minor things but this one is quite important: The
'mode' parameter in Work() tells you what you can do to the samples for
effect machines, generators can ignore it.

WM_READWRITE is the normal mode. 
WM_READ means you should only read but not write to the buffer. This
happens when machine is in <thru> mode (set in seq editor). 
WM_WRITE is the opposite. it happens when machine has no input (in other
words when all input samples are 0). Machines that generate output even
if there's no input should support this mode. That includes reverbs, delays
and even filters.
WM_NOIO means there's no input and you shouldn't write to the buffer.

In all cases, you should run your machine normally, but not read or write
to the buffer depending on the mode. If your machine's output doesn't
depend on past inputs you should "turn it off" to save cpu time when mode
is WM_READ or WM_NOIO. Reverbs and delays should turn themselves off after
they haven't had any input for a while (reverb/delay time).

Otherwise the code was fine. Nice work. :)

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com


Date: Fri, 26 Mar 1999 16:55:38 +0200 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: New machine released: JoyPlug 1 

At 09:31 AM 3/26/99 +0100, you wrote:
>This is something I've never quite understood.
>Isn't it better to have the same load on the computer
>all the time, instead of load changing?
>I guess not =)

Why the hell would it better? Low CPU usage is always better. We are not
talking about a game like quake where constant FPS rate is usually more
important. For example if part A of your song uses a machine connected to
reverb1 and part B uses machine connected to reverb2 you think it would be
better to run both reverbs all the time? :)

There's another reason too. When a feedback delay line runs for too long
without input it starts to generate floating point exceptions (too small
numbers). This makes it run around five times slower.

[Yes, the interrupt is masked but it's still very slow. anyone know the exact number of cycles wasted here?]

The machines are turned off when their output is so low that it can't be
heard so no-one can notice when it's turned off.

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com


Date: Fri, 09 Apr 1999 07:52:21 +0300 
From: Oskari Tammelin <ot@iki.fi> 
Subject: Re: resampling with dsplib 

>At 03:37 AM 6/19/98 -0500, you wrote:
>I'm having some trouble figuring out how to use the resampler in dsplib.
>If you want to resample some data to a given Rate, what do you set StepInt
>and StepFrac to?
>(or what do you pass to SetStep()?)
>Also, what is the difference between the two step modes?

I was going thru old buzz-dev mails and found this.. Maybe I should have
replied it earlier. :)

Step is the value to add to the sample read pointer for each sample. So
Step=2 would play the sample at double speed and Step=2^(1/12) would play
C#3 if the sample is sampled at C3. 

RSS_ONE means the resampler assumes Step=1 (happens often with percussive
samples) and doesn't do any resampling which is of course much faster.

RSS_CONSTANT means Step can be anything but stays constant. The resampler
doesn't support pitch sliding so there's no RSS_INTERPOLATE mode.
SetStep is just a helper function so you don't have to set StepInt and
StepFrac manually. You can use it or not.

Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com