Sound: Difference between revisions

From WSdev Wiki
Jump to navigationJump to search
(Register formatting.)
(adjust port category name formatting)
Line 41: Line 41:
== I/O Ports ==
== I/O Ports ==


=== Sound Channel Frequency ===
{{Anchor|Sound Channel Frequency}}
=== Sound Channel Frequency ($80, $81; $82, $83; $84, $85; $86, $87) ===


<pre>
<pre>
Line 55: Line 56:
Note that this refers to the sample rate of the ''wavetable'', and needs to be scaled accordingly for a given waveform when performing music playback.
Note that this refers to the sample rate of the ''wavetable'', and needs to be scaled accordingly for a given waveform when performing music playback.


=== Sound Channel Volume ===
{{Anchor|Sound Channel Volume}}
=== Sound Channel Volume ($88; $89; $8A; $8B) ===


<pre>
<pre>
Line 70: Line 72:
The calculation to get an unsigned 8-bit sample out of a 4-bit wavetable sample / 4-bit volume pair is simple: <code>out_sample = sample * volume</code>. This means that the maximum sample in wavetable output mode is <code>15 * 15 = 225</code>.
The calculation to get an unsigned 8-bit sample out of a 4-bit wavetable sample / 4-bit volume pair is simple: <code>out_sample = sample * volume</code>. This means that the maximum sample in wavetable output mode is <code>15 * 15 = 225</code>.


=== Sound Channel 2 Voice Sample ===
{{Anchor|Sound Channel 2 Voice Sample}}
=== Sound Channel 2 Voice Sample ($89) ===


<pre>
<pre>
Line 82: Line 85:
This sample is used for voice output.
This sample is used for voice output.


=== Sound Channel 3 Sweep Amount ===
{{Anchor|Sound Channel 3 Sweep Amount}}
=== Sound Channel 3 Sweep Amount ($8C) ===


<pre>
<pre>
Line 96: Line 100:
The signed value in this port will be added to the frequency divider for channel 3 every sweep step (as determined by the Sweep Ticks port). Wraparound is present - adding 1 to a frequency divider value of 2047 will cause it to roll over back to 0.
The signed value in this port will be added to the frequency divider for channel 3 every sweep step (as determined by the Sweep Ticks port). Wraparound is present - adding 1 to a frequency divider value of 2047 will cause it to roll over back to 0.


=== Sound Channel 3 Sweep Ticks ===
{{Anchor|Sound Channel 3 Sweep Ticks}}
=== Sound Channel 3 Sweep Ticks ($8D) ===


<pre>
<pre>
Line 110: Line 115:
Every <code>ttttt + 1</code> ticks, clocked at 375 Hz, the value in the Sweep Amount port will be added to the frequency divider for channel 3.
Every <code>ttttt + 1</code> ticks, clocked at 375 Hz, the value in the Sweep Amount port will be added to the frequency divider for channel 3.


=== Sound Channel 4 Noise Control ===
{{Anchor|Sound Channel 4 Noise Control}}
=== Sound Channel 4 Noise Control ($8F) ===


<pre>
<pre>
Line 170: Line 176:
# Use the new bit as if it were a wavetable sample: 0 = 0, 1 = 15.
# Use the new bit as if it were a wavetable sample: 0 = 0, 1 = 15.


=== Sound Wavetable Address ===
{{Anchor|Sound Wavetable Address}}
=== Sound Wavetable Address ($8F) ===


<pre>
<pre>
Line 206: Line 213:
Note that the ''higher'' bits - the first hexadecimal number - specify the ''later'' samples; that is to say, the nybbles of each sample are swapped relative to the wave drawing.
Note that the ''higher'' bits - the first hexadecimal number - specify the ''later'' samples; that is to say, the nybbles of each sample are swapped relative to the wave drawing.


=== Sound Channel Control ===
{{Anchor|Sound Channel Control}}
=== Sound Channel Control ($90) ===


<pre>
<pre>
Line 222: Line 230:
</pre>
</pre>


=== Sound Output Control ===
{{Anchor|Sound Output Control}}
=== Sound Output Control ($91) ===


<pre>
<pre>
Line 237: Line 246:
It is a good idea to set the internal speaker shift right value correctly. If the value is too low, multi-channel music will clip; if the value is too high, single-channel PCM sample playback will be very quiet.
It is a good idea to set the internal speaker shift right value correctly. If the value is too low, multi-channel music will clip; if the value is too high, single-channel PCM sample playback will be very quiet.


=== Sound Channel 4 LFSR Register ===
{{Anchor|Sound Channel 4 LFSR Register}}
=== Sound Channel 4 LFSR Register ($92, $93 read) ===


<pre>
<pre>
Line 247: Line 257:
</pre>
</pre>


=== Sound Channel 2 Voice Volume ===
{{Anchor|Sound Channel 2 Voice Volume}}
=== Sound Channel 2 Voice Volume ($94) ===


<pre>
<pre>

Revision as of 11:55, 22 August 2023

The WonderSwan features the following sound hardware:

  • Four audio channels:
    • channel 1 - wavetable (32 x 4-bit samples),
    • channel 2 - wavetable or 8-bit unsigned PCM sample,
    • channel 3 - wavetable with optional hardware sweep,
    • channel 4 - wavetable or LFSR noise,
  • Hyper Voice(color) - headphone output exclusive 16-bit stereo PCM output,
  • 24000 Hz output:
    • internal speaker - 8-bit, mono,
    • headphone output - 16-bit, stereo.

The sound is mixed as follows:

      Ch1 Ch2 Ch3 Ch4                        Glossary: L = left, R = right, M = mono 
       |   |   |   |                                               Mnn = nn-bit mono
       8   8   8   8      port $98                            port $nn =  value port
       |   |   |   |       /
      _V___V___V___V_     /              _____          _____
     |               |--L10------+------|     |        |     |
     |       +       |           |      |  +  |--M11-->| >>r |--M8--> Speaker output
     |_______________|--R10------|-+----|_____|  /     |_____|
                        /       _|_|_           /     (r=0...3)
                       /       |     |         /
                  port $96     | <<5 |      port $9A
                               |_____|
                                 | |
                                 | |
port $68            port $64     | |
 /    _______________   \      __V_V__                  _____
L8-->| (Color only)  |--L16-->|       |----------L16---|     |
     |  Hyper Voice  |        |  + +  |                | I2S |------> Headphone output
R8-->|_______________|--R16-->|_______|----------R16---|_____|
 \                      /
port $69            port $66

Hyper Voice functionality is documented on its own sub-page.

I/O Ports

Sound Channel Frequency ($80, $81; $82, $83; $84, $85; $86, $87)

15  bit  8  7  bit  0
 ---- ----  ---- ----
 .... .ddd  dddd dddd
       |||  |||| ||||
       +++--++++-++++- Frequency divisor

This frequency is used for wavetable output. It is calculated as follows: sample rate = 3072000 Hz / (2048 - divisor).

Note that this refers to the sample rate of the wavetable, and needs to be scaled accordingly for a given waveform when performing music playback.

Sound Channel Volume ($88; $89; $8A; $8B)

7  bit  0
---------
llll rrrr
|||| ||||
|||| ++++- Right channel volume (0-15)
++++------ Left channel volume (0-15)

This volume is used for wavetable output.

The calculation to get an unsigned 8-bit sample out of a 4-bit wavetable sample / 4-bit volume pair is simple: out_sample = sample * volume. This means that the maximum sample in wavetable output mode is 15 * 15 = 225.

Sound Channel 2 Voice Sample ($89)

7  bit  0
---- ----
ssss ssss
|||| ||||
++++-++++- Unsigned 8-bit PCM sample (0-255)

This sample is used for voice output.

Sound Channel 3 Sweep Amount ($8C)

7  bit  0
---- ----
vvvv vvvv
|||| ||||
++++-++++- Value; 8-bit, signed.

This port is used for wavetable output with sweep enabled.

The signed value in this port will be added to the frequency divider for channel 3 every sweep step (as determined by the Sweep Ticks port). Wraparound is present - adding 1 to a frequency divider value of 2047 will cause it to roll over back to 0.

Sound Channel 3 Sweep Ticks ($8D)

7  bit  0
---- ----
...t tttt
   | ||||
   +-++++- Ticks per step - 1

This port is used for wavetable output with sweep enabled.

Every ttttt + 1 ticks, clocked at 375 Hz, the value in the Sweep Amount port will be added to the frequency divider for channel 3.

Sound Channel 4 Noise Control ($8F)

7  bit  0
---- ----
...e rttt
   | ||||
   | |+++- LFSR tap mode
   | +---- LFSR reset: 1 = reset shift register
   +------ LFSR enabled: 0 = off, 1 = on

This port is used for noise output.

List of LFSR tap modes
Tap mode Tap bit Sequence length
0 14 32767
1 10 1953
2 13 254
3 4 217
4 8 73
5 6 63
6 9 42
7 11 28

Noise output works using the following algorithm, performed once per sample generated:

  1. Create a new bit by XORing bit 7 with the tap bit.
  2. Shift the LFSR register one bit to the left.
  3. Write the new bit as bit 0.
  4. Use the new bit as if it were a wavetable sample: 0 = 0, 1 = 15.

Sound Wavetable Address ($8F)

7  bit  0
---- ----
wwww wwww
|||| ||||
++++-++++- Wavetable address (bits 6-13)

The wavetable is 4 x 16 bytes long; each 16-byte block contains 32 4-bit samples for the relevant channel:

Address $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F
         98  CB  ED  FF  FF  EF  BD  8A  57  24  01  00  00  21  43  76
 Sample
     15  ..  ..  ..  ##  ##  #.  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
     14  ..  ..  .#  ||  ||  |#  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
     13  ..  ..  #|  ||  ||  ||  #.  ..  ..  ..  ..  ..  ..  ..  ..  ..
     12  ..  .#  ||  ||  ||  ||  |.  ..  ..  ..  ..  ..  ..  ..  ..  ..
     11  ..  #|  ||  ||  ||  ||  |#  ..  ..  ..  ..  ..  ..  ..  ..  ..
     10  ..  ||  ||  ||  ||  ||  ||  #.  ..  ..  ..  ..  ..  ..  ..  ..
      9  .#  ||  ||  ||  ||  ||  ||  |.  ..  ..  ..  ..  ..  ..  ..  ..
      8  #|  ||  ||  ||  ||  ||  ||  |#  ..  ..  ..  ..  ..  ..  ..  ..
      7  ||  ||  ||  ||  ||  ||  ||  ||  #.  ..  ..  ..  ..  ..  ..  .#
      6  ||  ||  ||  ||  ||  ||  ||  ||  |.  ..  ..  ..  ..  ..  ..  #|
      5  ||  ||  ||  ||  ||  ||  ||  ||  |#  ..  ..  ..  ..  ..  ..  ||
      4  ||  ||  ||  ||  ||  ||  ||  ||  ||  #.  ..  ..  ..  ..  .#  ||
      3  ||  ||  ||  ||  ||  ||  ||  ||  ||  |.  ..  ..  ..  ..  #|  ||
      2  ||  ||  ||  ||  ||  ||  ||  ||  ||  |#  ..  ..  ..  .#  ||  ||
      1  ||  ||  ||  ||  ||  ||  ||  ||  ||  ||  #.  ..  ..  #|  ||  ||
      0  ||  ||  ||  ||  ||  ||  ||  ||  ||  ||  |#  ##  ##  ||  ||  ||

Note that the higher bits - the first hexadecimal number - specify the later samples; that is to say, the nybbles of each sample are swapped relative to the wave drawing.

Sound Channel Control ($90)

7  bit  0
---- ----
nsv. 4321
|||  ||||
|||  |||+- Channel 1 enable
|||  ||+-- Channel 2 enable
|||  |+--- Channel 3 enable
|||  +---- Channel 4 enable
||+------- Channel 2 mode: 0 = wavetable, 1 = voice
|+-------- Channel 3 sweep: 0 = disable, 1 = enable
+--------- Channel 4 mode: 0 = wavetable, 1 = noise

Sound Output Control ($91)

7  bit  0
---- ----
H... hrrs
|    ||||
|    |||+- Internal speaker output enable
|    |++-- Internal speaker shift right value
|    +---- Headphone output enable
+--------- Headphones connected: 1 if true

It is a good idea to set the internal speaker shift right value correctly. If the value is too low, multi-channel music will clip; if the value is too high, single-channel PCM sample playback will be very quiet.

Sound Channel 4 LFSR Register ($92, $93 read)

15  bit  8  7  bit  0
 ---- ----  ---- ----
 .rrr rrrr  rrrr rrrr
  ||| ||||  |||| ||||
  +++-++++--++++-++++- Shift register value

Sound Channel 2 Voice Volume ($94)

7  bit  0
---- ----
.... lLrR
     ||||
     |||+- Right channel 100% volume
     ||+-- Right channel 50% volume
     |+--- Left channel 100% volume
     +---- Left channel 50% volume

This port is used for voice output.

The 50% volume have no effect if their respective 100% volume bits are set.