Difference between revisions of "Old BuzzDev Answers"

From Jeskola Buzz Wiki
Jump to: navigation, search
(formatting)
m (removed e-mails)
Line 1: Line 1:
 
'''SOMEONE PLEASE FORMAT THIS... OR DELETE IF ITS OLD AND OUTDATED STUFF'''
 
'''SOMEONE PLEASE FORMAT THIS... OR DELETE IF ITS OLD AND OUTDATED STUFF'''
 +
  
 
Answers by Oskari:
 
Answers by Oskari:
  
 
Date: Fri, 12 Jun 1998 20:12:27 +0300  
 
Date: Fri, 12 Jun 1998 20:12:27 +0300  
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: wavetable  
 
Subject: Re: wavetable  
  
Line 13: Line 14:
 
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.
 
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.
  
<pre>
+
<pre name="cpp">
 
virtual CWaveInfo const *GetWave(int const i);
 
virtual CWaveInfo const *GetWave(int const i);
 
virtual CWaveLevel const *GetWaveLevel(int const i, int const level);
 
virtual CWaveLevel const *GetWaveLevel(int const i, int const level);
Line 23: Line 24:
 
In tracker you just need to do this:
 
In tracker you just need to do this:
  
<pre>
+
<pre name="cpp">
 
CWaveInfo const *pWave = pCB->GetWave(pstate->iWave);
 
CWaveInfo const *pWave = pCB->GetWave(pstate->iWave);
 
CWaveLevel const *pLevel = pCB->GetNearestWaveLevel(pstate->iWave,
 
CWaveLevel const *pLevel = pCB->GetNearestWaveLevel(pstate->iWave,
Line 32: Line 33:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
-----------------------------------------------------------------------------
 
-----------------------------------------------------------------------------
  
 
Date: Tue, 16 Jun 1998 03:18:37 +0300
 
Date: Tue, 16 Jun 1998 03:18:37 +0300
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: importing .IT file samples
 
Subject: Re: importing .IT file samples
  
Line 49: Line 50:
 
Yep, just implement the Command() method:
 
Yep, just implement the Command() method:
  
<pre>
+
<pre name="cpp">
 
void mi::Command(int const i)
 
void mi::Command(int const i)
 
{
 
{
Line 64: Line 65:
 
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:
 
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:
  
<pre>
+
<pre name="cpp">
 
{
 
{
 
     MACHINE_LOCK  // this constructs a C++ object
 
     MACHINE_LOCK  // this constructs a C++ object
Line 74: Line 75:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
-----------------------------------------------------------------------------
 
-----------------------------------------------------------------------------
  
 
Date: Wed, 17 Jun 1998 07:03:05 +0100
 
Date: Wed, 17 Jun 1998 07:03:05 +0100
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: simple buzz tracker question
 
Subject: Re: simple buzz tracker question
  
Line 92: Line 93:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
-----------------------------------------------------------------------------
 
-----------------------------------------------------------------------------
  
 
Date: Fri, 26 Mar 1999 03:36:33 +0200
 
Date: Fri, 26 Mar 1999 03:36:33 +0200
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: New machine released: JoyPlug 1
 
Subject: Re: New machine released: JoyPlug 1
  
Line 119: Line 120:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
-----------------------------------------------------------------------------
 
-----------------------------------------------------------------------------
  
 
Date: Fri, 26 Mar 1999 16:55:38 +0200
 
Date: Fri, 26 Mar 1999 16:55:38 +0200
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: New machine released: JoyPlug 1
 
Subject: Re: New machine released: JoyPlug 1
  
Line 140: Line 141:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
-----------------------------------------------------------------------------
 
-----------------------------------------------------------------------------
  
 
Date: Fri, 09 Apr 1999 07:52:21 +0300
 
Date: Fri, 09 Apr 1999 07:52:21 +0300
From: Oskari Tammelin <ot@iki.fi>
+
From: Oskari Tammelin
 
Subject: Re: resampling with dsplib
 
Subject: Re: resampling with dsplib
  
Line 163: Line 164:
  
 
--
 
--
Oskari Tammelin .oOo. oskari@twilight3d.com .oOo. http://www.twilight3d.com
+
''Oskari Tammelin .oOo. http://www.twilight3d.com''
  
 
[[Category:Development]]
 
[[Category:Development]]

Revision as of 16:39, 11 July 2010

SOMEONE PLEASE FORMAT THIS... OR DELETE IF ITS OLD AND OUTDATED STUFF


Answers by Oskari:

Date: Fri, 12 Jun 1998 20:12:27 +0300 From: Oskari Tammelin 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,
pstate->Note);

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

-- Oskari Tammelin .oOo. http://www.twilight3d.com


Date: Tue, 16 Jun 1998 03:18:37 +0300 From: Oskari Tammelin 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 meantime 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 really 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)
{
        switch(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. http://www.twilight3d.com


Date: Wed, 17 Jun 1998 07:03:05 +0100 From: Oskari Tammelin 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. http://www.twilight3d.com


Date: Fri, 26 Mar 1999 03:36:33 +0200 From: Oskari Tammelin 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. http://www.twilight3d.com


Date: Fri, 26 Mar 1999 16:55:38 +0200 From: Oskari Tammelin Subject: Re: New machine released: JoyPlug 1

At 09:31 AM 3/26/99 +0100, you wrote: >Why? >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. http://www.twilight3d.com


Date: Fri, 09 Apr 1999 07:52:21 +0300 From: Oskari Tammelin 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. :) Anyway:

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. http://www.twilight3d.com