Jump to content
IGNORED

Sound in C with no library


vince

Recommended Posts

Where can I found a tutorial explaining how to access the sound hardware ?

 

Lynx documentation mentions a polynomial counter. How can I use it ?

 

The goal is not to use chipper nor play wav sample. I want to have a result like abcmusic purposes : providing values like taps for the polynomial counter, attack, hold, decay and obtaining a sound in the headphone.

 

 

Thanks in advance

Link to comment
Share on other sites

In order to produce sound you need a few values that you write to a few registers.

 

// The Atari Lynx audio system has 8 registers per audio
// channel that can be programmed to produce different
// waveforms.

#define STEREO_REG	 (*(char *)0xfd50)
#define VOLUME_REG(chan) (*(char *)(0xfd20 + 0 + (chan & 3) * )
#define FEED_REG(chan) (*(char *)(0xfd20 + 1 + (chan & 3) * )
#define OUT_REG(chan) (*(char *)(0xfd20 + 2 + (chan & 3) * )
#define SHIFT_REG(chan) (*(char *)(0xfd20 + 3 + (chan & 3) * )
#define BKUP_REG(chan) (*(char *)(0xfd20 + 4 + (chan & 3) * )
#define CTLA_REG(chan) (*(char *)(0xfd20 + 5 + (chan & 3) * )
#define CNT_REG(chan) (*(char *)(0xfd20 + 6 + (chan & 3) * )
#define CTLB_REG(chan) (*(char *)(0xfd20 + 7 + (chan & 3) * )

 

The first thing is the taps that define the actual shape of the audio. This also defines the length of the sound.

 

taps = 0x0019; // Looplen = 8

 

The next value is the backup register that is loaded to the counter at startup

 

backup = 0x00B1;

 

Then we have the prescaler that determines the octave in which we operate:

 

octave= 2;

 

Then we have the integrate bit that will sum the values.

 

integrate = 1;

 

Then we just write the values to the chips:

 

VOLUME_REG(chan) = 0;

STEREO_REG = 0;

// Disable count
CTLA_REG(chan) = 0x10;

// Setup new sound engine
FEED_REG(chan) = (taps & 0x003f) + ((taps >> 4) & 0xc0);
SHIFT_REG(chan) = backup & 0xff;
CTLB_REG(chan) = (backup >> 4) & 0xf0;
CTLA_REG(chan) = (taps & 0x0080) + 0x18 + octave + integrate << 5;

 

After this you can still change the pitch:

 

BKUP_REG(chan) = pitch;

 

or the volume:

 

VOLUME_REG(chan) = vol;

 

To find out what pitch matches which note I have used a table like this:

// This table is used to cover the delays needed for 4 octaves
// These values work when the looplen is 2, 4, 8, 16...
static char delays[] = {
    239,    // C,
    225,    // ^C, _D,
    213,    // D,
    201,    // ^D, _E,
    190,    // E,
    179,    // F,
    169,    // ^F, _G,
    159,    // G,
    151,    // ^G, _A,
    142,    // A,
    134,    // ^A, _B,
    127,    // B,
    119,    // C
    113,    // ^C _D
    106,    // D
    100,    // ^D _E
    95,	 // E
    89,	 // F
    84,	 // ^F _G
    80,	 // G
    75,	 // ^G  _A
    71,	 // A
    67,	 // ^A _B
    63,	 // B
    60,	 // c
    56,	 // ^c _d
    53,	 // d
    50,	 // ^d _e
    47,	 // e
    45,	 // f
    42,	 // ^f _g
    40,	 // g
    38,	 // ^g _a
    36,	 // a
    34,	 // ^a _b
    32,	 // b
    30,	 // c'
    28,	 // ^c' _d'
    27,	 // d'
    25,	 // ^d' _e'
    24,	 // e'
    22,	 // f'
    21,	 // ^f' _g'
    20,	 // g'
    19,	 // ^g' _a'
    18,	 // a'
    17,	 // ^a' _b'
    16	  // b'
};

Edited by karri
  • Like 1
Link to comment
Share on other sites

Another question : 0x0019 is for the shape of the sound but I don't understand why you set the backup too 0x00B1... Do the backup value depends on the taps value ?

 

Shape depends on feedback taps AND shift register.

no idea why Karri name it backup. for a list of feedback/shifter combinations, their shape length any type, you can check chipper.

Edited by sage
Link to comment
Share on other sites

I believe it was called backup-register in the Epyx manual or tools.

 

Some years ago I did a large study to find out how many unique waveforms the Lynx can produce. The answer was 6175 or something like that. In any case I sorted the waveforms by length into a giant table and produced a tool called "soundtool" from it. It is included on MegaPak 1.

 

The idea is that you can listed to all available waveforms and if you find a sound you like you can write down the register values to produce the same sound in your game. Waveform 0 is just a square wave while at the end of the list the list the length is 4095 bits long.

 

As the waveformes are sorted by length I can easily listen to sounds close to each other and use the same pitch values and expect the same note height from the neighbour waveforms.

 

post-2099-0-77528700-1354469866_thumb.png

 

The user interface is quite crude. The green Symmetric waveform means that it has an equal number of ones and zeros in it.

Edited by karri
Link to comment
Share on other sites

Here are all good (symmetric) combinations for taps and backup for these loop lengths.

In my opinion these are the only usable combinations for setting up instruments based on the built-in hardware. All these combinations produce an unique sound.

The first value is for taps the next values on the line for backup.

 

Loop length 2:

0x0001 0x0001

 

Loop length 4:

0x0002 0x0006

 

Loop length 8:

0x0008 0x0078 0x0069
0x0019 0x00B1 0x0072
0x002A 0x00E2 0x00A3 0x0065 0x00A6

 

Loop length 16:

0x0080 0x0F80 0x0E81 0x0D82 0x0C83 0x0B84 0x0A85 0x0986 0x0887 0x0689
0x0080 0x058A 0x048B 0x038C 0x028D 0x0D92 0x0A95 0x0996
0x0484 0x0C16 0x041E 0x0C29 0x0C36 0x0C39 0x043E 0x0C46 0x044E 0x0C66
0x0484 0x0C69 0x0C79 0x0C99
0x0888 0x0819 0x081B 0x081D 0x081F 0x082A 0x082B 0x082E 0x082F 0x0833 0x0837
0x0888 0x0839 0x083A 0x083D 0x083E 0x084C 0x084D 0x084E 0x084F 0x0855 0x0857
0x0888 0x0859 0x085B 0x085C 0x085E 0x0866 0x0867 0x086A 0x086B 0x086C 0x086D
0x0888 0x0873 0x0875 0x0876 0x0879 0x087A 0x087C 0x0891 0x0893 0x0895 0x0897
0x0888 0x0899 0x089B 0x089D 0x089F 0x08A2 0x08A3 0x08A6 0x08A7 0x08AA 0x08AB
0x0888 0x08AE 0x08AF 0x08B1 0x08B2 0x08B5 0x08B6 0x08B9 0x08BA 0x08BD 0x08C6
0x0888 0x08C7 0x08CC 0x08CD 0x08CE 0x08CF 0x08D1 0x08D3 0x08D4 0x08D6 0x08D9
0x0888 0x08DE 0x08E3 0x08E4 0x08E5 0x08EB 0x08ED 0x08F2 0x08F4 0x0927 0x0929
0x0888 0x092A 0x092D 0x092E 0x0932 0x0933 0x0937 0x094B 0x094C 0x0955 0x0956
0x0888 0x0959 0x095A 0x0966 0x0969 0x096A 0x09A6

Link to comment
Share on other sites

Mmm, pressed Post but didn't seem to come through.

I need some help reading these values. I cannot see what are the backup values (loops perhaps?) and what values go into the taps (12 bits shift register, right?).

Could you explain.

 

The first value on each row is the taps value and the rest are suitable backup-values.

 

Example Loop length 8:

 

taps = 0x0008 backup = 0x0078 is one kind of instrument sound

taps = 0x0008 backup = 0x0069 is another sound

taps = 0x0019 backup = 0x00B1 is a third sound

taps = 0x0019 backup = 0x0072 is a fourth sound

...

 

All these loop length 8 sounds have the same frequency so you can make an orchestra with different "instruments" by picking values from this table. So it you play note "C" it has the same pitch in all these instruments.

 

--

Karri

Link to comment
Share on other sites

btw: you will find a "full" list of shifter and feedback taps sorted by polycound length in data/polysort.dat in the chipper package.

 

full in the sense that each waveform is listed only once (from its *length occurances).

 

Example:

3255,801,000,-1,3

 

length, shifter, feedback, <some flags used by chipper...>

the shifter and feedback are in hex (3255, $801, $000)

 

if you click on the list in chipper, you will get a display of the waveform.

(in the waveform or simple instrument window)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...