Merge branch 'tildearrow:master' into master
This commit is contained in:
commit
21d11c64b4
|
@ -15,8 +15,8 @@ android {
|
||||||
}
|
}
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 174
|
versionCode 175
|
||||||
versionName "0.6pre13"
|
versionName "0.6pre14"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DWARNINGS_ARE_ERRORS=ON"
|
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DWARNINGS_ARE_ERRORS=ON"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.tildearrow.furnace"
|
package="org.tildearrow.furnace"
|
||||||
android:versionCode="174"
|
android:versionCode="175"
|
||||||
android:versionName="0.6pre13"
|
android:versionName="0.6pre14"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
|
||||||
<!-- OpenGL ES 2.0 -->
|
<!-- OpenGL ES 2.0 -->
|
||||||
|
|
BIN
demos/arcade/WSG_Loop_Tune_NamcoWSG.fur
Normal file
BIN
demos/arcade/WSG_Loop_Tune_NamcoWSG.fur
Normal file
Binary file not shown.
BIN
demos/gameboy/On_Hold.fur
Normal file
BIN
demos/gameboy/On_Hold.fur
Normal file
Binary file not shown.
BIN
demos/multichip/PinBot-C30C140.fur
Normal file
BIN
demos/multichip/PinBot-C30C140.fur
Normal file
Binary file not shown.
BIN
demos/x16/Exerion_II_Tune.fur
Normal file
BIN
demos/x16/Exerion_II_Tune.fur
Normal file
Binary file not shown.
|
@ -148,19 +148,53 @@ additionally, [each chip has its own effects](../7-systems/README.md).
|
||||||
|
|
||||||
the interpretation of duty, wave and extra macros depends on chip/instrument type:
|
the interpretation of duty, wave and extra macros depends on chip/instrument type:
|
||||||
|
|
||||||
ex | FM | OPM | OPZ | OPLL | AY-3-8910 | AY8930 | Lynx | C64 | SAA1099 | X1-010 | Namco 163 | FDS | Sound Unit | ES5506 | MSM6258 | QSound | SNES | MSM5232 |
|
ex | FM | OPM | OPZ | OPLL | AY-3-8910 | AY8930 | Lynx | C64 |
|
||||||
---|--------|-----------|-----------|-------|------------|------------|----------|------------|----------|------------|------------|-----------|------------|-----------|----------|--------------|-----------|-----------|
|
---|--------|-----------|-----------|-------|------------|------------|----------|------------|
|
||||||
D | NoiseF | NoiseFreq | | | NoiseFreq | NoiseFreq | Duty/Int | Duty | | | Wave Pos | | Duty | Filt Mode | FreqDiv | Echo Level | NoiseFreq | GroupCtrl |
|
D | NoiseF | NoiseFreq | | | NoiseFreq | NoiseFreq | Duty/Int | Duty |
|
||||||
W | | LFO Shape | LFO Shape | Patch | Waveform | Waveform | | Waveform | Waveform | Waveform | Waveform | Waveform | Waveform | | | | Waveform | |
|
W | | LFO Shape | LFO Shape | Patch | Waveform | Waveform | | Waveform |
|
||||||
1 | | AMD | AMD | | | Duty | | FilterMode | Envelope | EnvMode | WaveLen | Mod Depth | Cutoff | Filter K1 | ClockDiv | EchoFeedback | Special | GroupAtk |
|
1 | | AMD | AMD | | | Duty | | FilterMode |
|
||||||
2 | | PMD | PMD | | Envelope | Envelope | | Resonance | | Envelope | WaveUpdate | Mod Speed | Resonance | Filter K2 | | Echo Length | Gain | GroupDec |
|
2 | | PMD | PMD | | Envelope | Envelope | | Resonance |
|
||||||
3 | LFOSpd | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | Special | | AutoEnvNum | WaveLoad W | | Control | Env Count | | | | Noise |
|
3 | LFOSpd | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | Special |
|
||||||
A | ALG | ALG | ALG | | AutoEnvDen | AutoEnvDen | | | | AutoEnvDen | WaveLoad P | | | Control | | | | |
|
A | ALG | ALG | ALG | | AutoEnvDen | AutoEnvDen | | |
|
||||||
B | FB | FB | FB | | | Noise AND | | | | | WaveLoad L | | | | | | | |
|
B | FB | FB | FB | | | Noise AND | | |
|
||||||
C | FMS | FMS | FMS | | | Noise OR | | | | | WaveLoad T | | | | | | | |
|
C | FMS | FMS | FMS | | | Noise OR | | |
|
||||||
D | AMS | AMS | AMS | | | | | | | | | | | | | | | |
|
D | AMS | AMS | AMS | | | | | |
|
||||||
4 | OpMask | OpMask | | | | | | Test/Gate | | | | | PResetTime | EnvRampL | | | | |
|
4 | OpMask | OpMask | | | | | | Test/Gate |
|
||||||
5 | | | AMD2 | | | | | | | | | | | EnvRampR | | | | |
|
5 | | | AMD2 | | | | | |
|
||||||
6 | | | PMD2 | | | | | | | | | | | EnvRampK1 | | | | |
|
6 | | | PMD2 | | | | | |
|
||||||
7 | | | LFO2Speed | | | | | | | | | | | EnvRampK2 | | | | |
|
7 | | | LFO2Speed | | | | | |
|
||||||
8 | | | LFO2Shape | | | | | | | | | | | Env Mode | | | | |
|
8 | | | LFO2Shape | | | | | |
|
||||||
|
|
||||||
|
ex | SAA1099 | X1-010 | Namco 163 | FDS | Sound Unit | ES5506 | MSM6258 |
|
||||||
|
---|----------|------------|------------|-----------|------------|-----------|----------|
|
||||||
|
D | | | Wave Pos | | Duty | Filt Mode | FreqDiv |
|
||||||
|
W | Waveform | Waveform | Waveform | Waveform | Waveform | | |
|
||||||
|
1 | Envelope | EnvMode | WaveLen | Mod Depth | Cutoff | Filter K1 | ClockDiv |
|
||||||
|
2 | | Envelope | WaveUpdate | Mod Speed | Resonance | Filter K2 | |
|
||||||
|
3 | | AutoEnvNum | WaveLoad W | | Control | Env Count | |
|
||||||
|
A | | AutoEnvDen | WaveLoad P | | | Control | |
|
||||||
|
B | | | WaveLoad L | | | | |
|
||||||
|
C | | | WaveLoad T | | | | |
|
||||||
|
D | | | | | | | |
|
||||||
|
4 | | | | | PResetTime | EnvRampL | |
|
||||||
|
5 | | | | | | EnvRampR | |
|
||||||
|
6 | | | | | | EnvRampK1 | |
|
||||||
|
7 | | | | | | EnvRampK2 | |
|
||||||
|
8 | | | | | | Env Mode | |
|
||||||
|
|
||||||
|
ex | QSound | SNES | MSM5232 |
|
||||||
|
---|--------------|-----------|-----------|
|
||||||
|
D | Echo Level | NoiseFreq | GroupCtrl |
|
||||||
|
W | | Waveform | |
|
||||||
|
1 | EchoFeedback | Special | GroupAtk |
|
||||||
|
2 | Echo Length | Gain | GroupDec |
|
||||||
|
3 | | | Noise |
|
||||||
|
A | | | |
|
||||||
|
B | | | |
|
||||||
|
C | | | |
|
||||||
|
D | | | |
|
||||||
|
4 | | | |
|
||||||
|
5 | | | |
|
||||||
|
6 | | | |
|
||||||
|
7 | | | |
|
||||||
|
8 | | | |
|
||||||
|
|
|
@ -26,4 +26,4 @@ MSM6258 is an extremely basic ADPCM sound codec. it has no variable frequency ra
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [MSM6258](../4-instrument/msm6258.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [MSM6258](../4-instrument/msm6258.md) instrument editor.
|
||||||
|
|
|
@ -10,7 +10,7 @@ an upgrade from 6258 - it provides 4 ADPCM channels, at max 32 KHz (still no var
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [MSM6295](../4-instrument/msm6295.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [MSM6295](../4-instrument/msm6295.md) instrument editor.
|
||||||
|
|
||||||
## chip clock rates
|
## chip clock rates
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ also known as Famicom. it is a five-channel sound generator: first two channels
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [NES](../4-instrument/nes.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [NES](../4-instrument/nes.md) instrument editor.
|
||||||
|
|
||||||
## short noise frequencies (NTSC)
|
## short noise frequencies (NTSC)
|
||||||
|
|
||||||
|
|
|
@ -23,4 +23,4 @@ furthermore, it has some PCM and LFO!
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [PC Engine](../4-instrument/pce.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [PC Engine](../4-instrument/pce.md) instrument editor.
|
||||||
|
|
|
@ -21,4 +21,4 @@ there are also 3 ADPCM channels. ADPCM samples are fixed to 8012Hz.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [QSound](../4-instrument/qsound.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [QSound](../4-instrument/qsound.md) instrument editor.
|
||||||
|
|
|
@ -8,4 +8,4 @@ none so far.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [RF5C68](../4-instrument/rf5c68.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [RF5C68](../4-instrument/rf5c68.md) instrument editor.
|
||||||
|
|
|
@ -18,4 +18,4 @@ Furnace also has a five channel version of this chip, but it only exists for Def
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [SegaPCM](../4-instrument/segapcm.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [SegaPCM](../4-instrument/segapcm.md) instrument editor.
|
||||||
|
|
|
@ -57,4 +57,4 @@ it has the following capabilities:
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [Sound Unit](../4-instrument/su.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [Sound Unit](../4-instrument/su.md) instrument editor.
|
||||||
|
|
|
@ -20,4 +20,4 @@ these effects only are effective in the pulse channels.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [VRC6](../4-instrument/vrc6.md), [VRC6 (saw)](../4-instrument/vrc6.md), and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [VRC6](../4-instrument/vrc6.md) and [VRC6 (saw)](../4-instrument/vrc6.md) instrument editors.
|
||||||
|
|
|
@ -18,7 +18,9 @@ it has 4 wavetable channels. some of them have additional capabilities:
|
||||||
- 0: disable.
|
- 0: disable.
|
||||||
- 1-32: enable and set period.
|
- 1-32: enable and set period.
|
||||||
- `13xx`: **setup sweep amount.** channel 3 only.
|
- `13xx`: **setup sweep amount.** channel 3 only.
|
||||||
|
- `00` to `7F` for 0 to 127.
|
||||||
|
- `80` to `FF` for -128 to -1.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [WonderSwan](../4-instrument/wonderswan.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [WonderSwan](../4-instrument/wonderswan.md) instrument editor.
|
||||||
|
|
|
@ -49,4 +49,4 @@ in Furnace, you can enable the envelope shape split mode. when it is set, its wa
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [X1-010](../4-instrument/x1_010.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [X1-010](../4-instrument/x1_010.md) instrument editor.
|
||||||
|
|
|
@ -108,6 +108,4 @@ all four operators are still combined according to the algorithm in use. for exa
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [Generic Sample](../4-instrument/sample.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md), and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md) and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,4 @@ all four operators are still combined according to the algorithm in use. for exa
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [Generic Sample](../4-instrument/sample.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md), and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md) and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,4 @@ all four operators are still combined according to the algorithm in use. for exa
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [Generic Sample](../4-instrument/sample.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md), and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md), [AY-3-8910/SSG](../4-instrument/ay8910.md), [ADPCM-A](../4-instrument/adpcm-a.md) and [ADPCM-B](../4-instrument/adpcm-b.md) instrument editors.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,5 +86,3 @@ thanks to the Z80 sound CPU, DualPCM can play two samples at once! this mode spl
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [FM (OPN)](../4-instrument/fm-opn.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,4 @@ none so far.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [YMZ280B](../4-instrument/ymz280b.md) and [Generic Sample](../4-instrument/sample.md) instrument editors.
|
this chip uses the [YMZ280B](../4-instrument/ymz280b.md) instrument editor.
|
||||||
|
|
|
@ -17,4 +17,4 @@ not really - very soon talented programmers found out ways to output much more t
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [Beeper](../4-instrument/beeper.md), [Generic Sample](../4-instrument/sample.md), and [Pokémon Mini/QuadTone](../4-instrument/pokemini.md) instrument editors.
|
this chip uses the [Beeper](../4-instrument/beeper.md) or [Pokémon Mini/QuadTone](../4-instrument/pokemini.md) instrument editor.
|
||||||
|
|
|
@ -6,7 +6,7 @@ when copying pattern data from Furnace, it's stored in the clipboard as plain te
|
||||||
org.tildearrow.furnace - Pattern Data (144)
|
org.tildearrow.furnace - Pattern Data (144)
|
||||||
```
|
```
|
||||||
|
|
||||||
this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6pre13 is `174`.
|
this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6pre14 is `175`.
|
||||||
|
|
||||||
the second line is a number between 0 and 18 (decimal) which indicates which column the clip starts from.
|
the second line is a number between 0 and 18 (decimal) which indicates which column the clip starts from.
|
||||||
- `0`: note.
|
- `0`: note.
|
||||||
|
|
|
@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 175: Furnace 0.6pre14
|
||||||
- 174: Furnace 0.6pre13
|
- 174: Furnace 0.6pre13
|
||||||
- 173: Furnace 0.6pre12
|
- 173: Furnace 0.6pre12
|
||||||
- 172: Furnace 0.6pre11
|
- 172: Furnace 0.6pre11
|
||||||
|
|
|
@ -15,17 +15,17 @@
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleLongVersionString</key>
|
<key>CFBundleLongVersionString</key>
|
||||||
<string>0.6pre13</string>
|
<string>0.6pre14</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Furnace</string>
|
<string>Furnace</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.6pre13</string>
|
<string>0.6pre14</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.6pre13</string>
|
<string>0.6pre14</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
|
|
|
@ -91,7 +91,7 @@ if __name__ == "__main__":
|
||||||
# each file is its own section
|
# each file is its own section
|
||||||
html +='<section id="%s">%s</section>' % (
|
html +='<section id="%s">%s</section>' % (
|
||||||
my_file.replace(os.path.sep, "__"),
|
my_file.replace(os.path.sep, "__"),
|
||||||
markdown.markdown(data, extensions=['nl2br', GithubFlavoredMarkdownExtension()])
|
markdown.markdown(data, extensions=['nl2br', 'mdx_breakless_lists', GithubFlavoredMarkdownExtension()])
|
||||||
)
|
)
|
||||||
|
|
||||||
# build html
|
# build html
|
||||||
|
@ -119,7 +119,7 @@ if __name__ == "__main__":
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-family: 'Exo 2';
|
font-family: 'Exo 2';
|
||||||
line-height: 1.2;
|
line-height: 1.25;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ if __name__ == "__main__":
|
||||||
font-family: 'IBM Plex Mono';
|
font-family: 'IBM Plex Mono';
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
padding-left: 4pt;
|
padding-left: 10pt;
|
||||||
margin-right: 4pt;
|
margin-right: 4pt;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
@ -184,13 +184,13 @@ if __name__ == "__main__":
|
||||||
}
|
}
|
||||||
a[href^='#']:after {
|
a[href^='#']:after {
|
||||||
content: target-counter(attr(href),page);
|
content: target-counter(attr(href),page);
|
||||||
font-weight: regular;
|
font-weight: normal;
|
||||||
font-size: 0.5em;
|
font-size: 0.5em;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
a[href^='http']:after {
|
a[href^='http']:after {
|
||||||
content: ' (' attr(href) ') ';
|
content: ' (' attr(href) ') ';
|
||||||
font-weight: regular;
|
font-weight: normal;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
#cover {
|
#cover {
|
||||||
|
@ -209,10 +209,12 @@ if __name__ == "__main__":
|
||||||
pre {
|
pre {
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
}
|
}
|
||||||
|
li > p {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
table {
|
table {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%%;
|
width: 100%%;
|
||||||
width: max-content;
|
|
||||||
max-width: 100%%;
|
max-width: 100%%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
@ -222,14 +224,17 @@ if __name__ == "__main__":
|
||||||
border-top: 1pt solid #aaa;
|
border-top: 1pt solid #aaa;
|
||||||
}
|
}
|
||||||
th, td {
|
th, td {
|
||||||
padding: 3pt 6pt;
|
padding: 2pt 3pt;
|
||||||
border: 1pt solid #ccc;
|
border: 1pt solid #ccc;
|
||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
hyphens: none;
|
hyphens: none;
|
||||||
padding: 2pt 4pt;
|
padding: 2pt 4pt;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: .8em
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
@page {
|
@page {
|
||||||
size: a4;
|
size: a4;
|
||||||
|
|
|
@ -5,6 +5,7 @@ fonttools==4.39.3
|
||||||
html5lib==1.1
|
html5lib==1.1
|
||||||
Markdown==3.4.3
|
Markdown==3.4.3
|
||||||
Pillow==9.4.0
|
Pillow==9.4.0
|
||||||
|
mdx-breakless-lists==1.0.1
|
||||||
py-gfm==2.0.0
|
py-gfm==2.0.0
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
pydyf==0.5.0
|
pydyf==0.5.0
|
||||||
|
|
|
@ -3246,6 +3246,10 @@ void DivEngine::setMetronomeVol(float vol) {
|
||||||
metroVol=vol;
|
metroVol=vol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivEngine::setSamplePreviewVol(float vol) {
|
||||||
|
previewVol=vol;
|
||||||
|
}
|
||||||
|
|
||||||
void DivEngine::setConsoleMode(bool enable) {
|
void DivEngine::setConsoleMode(bool enable) {
|
||||||
consoleMode=enable;
|
consoleMode=enable;
|
||||||
}
|
}
|
||||||
|
@ -3450,6 +3454,7 @@ bool DivEngine::initAudioBackend() {
|
||||||
clampSamples=getConfInt("clampSamples",0);
|
clampSamples=getConfInt("clampSamples",0);
|
||||||
lowLatency=getConfInt("lowLatency",0);
|
lowLatency=getConfInt("lowLatency",0);
|
||||||
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
||||||
|
previewVol=(float)(getConfInt("sampleVol",50))/100.0f;
|
||||||
midiOutClock=getConfInt("midiOutClock",0);
|
midiOutClock=getConfInt("midiOutClock",0);
|
||||||
midiOutTime=getConfInt("midiOutTime",0);
|
midiOutTime=getConfInt("midiOutTime",0);
|
||||||
midiOutTimeRate=getConfInt("midiOutTimeRate",0);
|
midiOutTimeRate=getConfInt("midiOutTimeRate",0);
|
||||||
|
@ -3457,6 +3462,8 @@ bool DivEngine::initAudioBackend() {
|
||||||
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
||||||
if (metroVol<0.0f) metroVol=0.0f;
|
if (metroVol<0.0f) metroVol=0.0f;
|
||||||
if (metroVol>2.0f) metroVol=2.0f;
|
if (metroVol>2.0f) metroVol=2.0f;
|
||||||
|
if (previewVol<0.0f) previewVol=0.0f;
|
||||||
|
if (previewVol>1.0f) previewVol=1.0f;
|
||||||
renderPoolThreads=getConfInt("renderPoolThreads",0);
|
renderPoolThreads=getConfInt("renderPoolThreads",0);
|
||||||
|
|
||||||
if (lowLatency) logI("using low latency mode.");
|
if (lowLatency) logI("using low latency mode.");
|
||||||
|
|
|
@ -58,8 +58,8 @@ class DivWorkPool;
|
||||||
|
|
||||||
#define DIV_UNSTABLE
|
#define DIV_UNSTABLE
|
||||||
|
|
||||||
#define DIV_VERSION "0.6pre13"
|
#define DIV_VERSION "0.6pre14"
|
||||||
#define DIV_ENGINE_VERSION 174
|
#define DIV_ENGINE_VERSION 175
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
@ -490,6 +490,7 @@ class DivEngine {
|
||||||
float metroFreq, metroPos;
|
float metroFreq, metroPos;
|
||||||
float metroAmp;
|
float metroAmp;
|
||||||
float metroVol;
|
float metroVol;
|
||||||
|
float previewVol;
|
||||||
|
|
||||||
size_t totalProcessed;
|
size_t totalProcessed;
|
||||||
|
|
||||||
|
@ -729,6 +730,9 @@ class DivEngine {
|
||||||
int getSamplePreviewPos();
|
int getSamplePreviewPos();
|
||||||
double getSamplePreviewRate();
|
double getSamplePreviewRate();
|
||||||
|
|
||||||
|
// set sample preview volume (1.0 = 100%)
|
||||||
|
void setSamplePreviewVol(float vol);
|
||||||
|
|
||||||
// trigger sample preview
|
// trigger sample preview
|
||||||
void previewSample(int sample, int note=-1, int pStart=-1, int pEnd=-1);
|
void previewSample(int sample, int note=-1, int pStart=-1, int pEnd=-1);
|
||||||
void stopSamplePreview();
|
void stopSamplePreview();
|
||||||
|
@ -1282,6 +1286,7 @@ class DivEngine {
|
||||||
metroPos(0),
|
metroPos(0),
|
||||||
metroAmp(0.0f),
|
metroAmp(0.0f),
|
||||||
metroVol(1.0f),
|
metroVol(1.0f),
|
||||||
|
previewVol(1.0f),
|
||||||
totalProcessed(0),
|
totalProcessed(0),
|
||||||
renderPoolThreads(0),
|
renderPoolThreads(0),
|
||||||
renderPool(NULL),
|
renderPool(NULL),
|
||||||
|
|
|
@ -152,11 +152,18 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (is219) {
|
if (is219) {
|
||||||
if (chan[i].std.duty.had) {
|
if (chan[i].std.duty.had) {
|
||||||
chan[i].noise=chan[i].std.duty.val&1;
|
unsigned char singleByte=(
|
||||||
chan[i].invert=chan[i].std.duty.val&2;
|
(chan[i].noise?1:0)|
|
||||||
chan[i].surround=chan[i].std.duty.val&4;
|
(chan[i].invert?2:0)|
|
||||||
chan[i].freqChanged=true;
|
(chan[i].surround?4:0)
|
||||||
chan[i].writeCtrl=true;
|
);
|
||||||
|
if (singleByte!=(chan[i].std.duty.val&7)) {
|
||||||
|
chan[i].noise=chan[i].std.duty.val&1;
|
||||||
|
chan[i].invert=chan[i].std.duty.val&2;
|
||||||
|
chan[i].surround=chan[i].std.duty.val&4;
|
||||||
|
chan[i].freqChanged=true;
|
||||||
|
chan[i].writeCtrl=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.pitch.had) {
|
if (chan[i].std.pitch.had) {
|
||||||
|
@ -209,7 +216,7 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
if (chan[i].freq<0) chan[i].freq=0;
|
if (chan[i].freq<0) chan[i].freq=0;
|
||||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||||
if (is219) {
|
if (is219) {
|
||||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_C219)?1:0)|(chan[i].invert?0x40:0)|(chan[i].surround?8:0)|(chan[i].noise?4:0);
|
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable() || chan[i].noise)?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_C219)?1:0)|(chan[i].invert?0x40:0)|(chan[i].surround?8:0)|(chan[i].noise?4:0);
|
||||||
} else {
|
} else {
|
||||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_MULAW)?0x08:0);
|
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_MULAW)?0x08:0);
|
||||||
}
|
}
|
||||||
|
@ -228,11 +235,15 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
start=sampleOff[chan[i].sample]&0xffff;
|
start=sampleOff[chan[i].sample]&0xffff;
|
||||||
end=MIN(start+s->length8-1,65535);
|
end=MIN(start+s->length8-1,65535);
|
||||||
}
|
}
|
||||||
|
} else if (chan[i].noise && is219) {
|
||||||
|
bank=groupBank[i>>2];
|
||||||
|
start=0;
|
||||||
|
end=1;
|
||||||
}
|
}
|
||||||
if (chan[i].audPos>0) {
|
if (chan[i].audPos>0) {
|
||||||
start=MIN(start+(MIN(chan[i].audPos,s->length8)>>1),65535);
|
start=MIN(start+(MIN(chan[i].audPos,s->length8)>>1),65535);
|
||||||
}
|
}
|
||||||
if (s->isLoopable()) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen && s->isLoopable()) {
|
||||||
if (is219) {
|
if (is219) {
|
||||||
loop=MIN(start+(s->loopStart>>1),65535);
|
loop=MIN(start+(s->loopStart>>1),65535);
|
||||||
end=MIN(start+(s->loopEnd>>1)-1,65535);
|
end=MIN(start+(s->loopEnd>>1)-1,65535);
|
||||||
|
@ -240,6 +251,8 @@ void DivPlatformC140::tick(bool sysTick) {
|
||||||
loop=MIN(start+s->loopStart,65535);
|
loop=MIN(start+s->loopStart,65535);
|
||||||
end=MIN(start+s->loopEnd-1,65535);
|
end=MIN(start+s->loopEnd-1,65535);
|
||||||
}
|
}
|
||||||
|
} else if (chan[i].noise && is219) {
|
||||||
|
loop=0;
|
||||||
}
|
}
|
||||||
rWrite(0x05+(i<<4),0); // force keyoff first
|
rWrite(0x05+(i<<4),0); // force keyoff first
|
||||||
if (is219) {
|
if (is219) {
|
||||||
|
|
|
@ -30,6 +30,16 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int msmRates[4]={
|
||||||
|
4, 3, 2, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
int DivPlatformMSM6258::calcVGMRate() {
|
||||||
|
int ret=chipClock/((clockSel+1)*512*msmRates[rateSel&3]);
|
||||||
|
logD("MSM rate: %d",ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
|
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
if (--msmClockCount<0) {
|
if (--msmClockCount<0) {
|
||||||
|
@ -93,6 +103,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
||||||
if (rateSel!=(chan[i].std.duty.val&3)) {
|
if (rateSel!=(chan[i].std.duty.val&3)) {
|
||||||
rateSel=chan[i].std.duty.val&3;
|
rateSel=chan[i].std.duty.val&3;
|
||||||
rWrite(12,rateSel);
|
rWrite(12,rateSel);
|
||||||
|
updateSampleFreq=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.panL.had) {
|
if (chan[i].std.panL.had) {
|
||||||
|
@ -105,6 +116,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
||||||
if (clockSel!=(chan[i].std.ex1.val&1)) {
|
if (clockSel!=(chan[i].std.ex1.val&1)) {
|
||||||
clockSel=chan[i].std.ex1.val&1;
|
clockSel=chan[i].std.ex1.val&1;
|
||||||
rWrite(8,clockSel);
|
rWrite(8,clockSel);
|
||||||
|
updateSampleFreq=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.phaseReset.had) {
|
if (chan[i].std.phaseReset.had) {
|
||||||
|
@ -113,12 +125,23 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (updateSampleFreq) {
|
||||||
|
int newRate=calcVGMRate();
|
||||||
|
if (dumpWrites) addWrite(0xffff0001,newRate);
|
||||||
|
updateSampleFreq=false;
|
||||||
|
}
|
||||||
if (chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].keyOn || chan[i].keyOff) {
|
||||||
samplePos=0;
|
samplePos=0;
|
||||||
rWrite(0,1); // turn off
|
// turn off
|
||||||
|
if (dumpWrites) addWrite(0xffff0002,0);
|
||||||
|
rWrite(0,1);
|
||||||
if (chan[i].active && !chan[i].keyOff) {
|
if (chan[i].active && !chan[i].keyOff) {
|
||||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||||
|
// turn on
|
||||||
rWrite(0,2);
|
rWrite(0,2);
|
||||||
|
if (dumpWrites) addWrite(0xffff0000,sample);
|
||||||
|
int newRate=calcVGMRate();
|
||||||
|
if (dumpWrites) addWrite(0xffff0001,newRate);
|
||||||
} else {
|
} else {
|
||||||
sample=-1;
|
sample=-1;
|
||||||
}
|
}
|
||||||
|
@ -220,10 +243,12 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_SAMPLE_FREQ:
|
case DIV_CMD_SAMPLE_FREQ:
|
||||||
rateSel=c.value&3;
|
rateSel=c.value&3;
|
||||||
rWrite(12,rateSel);
|
rWrite(12,rateSel);
|
||||||
|
updateSampleFreq=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_MODE:
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
clockSel=c.value&1;
|
clockSel=c.value&1;
|
||||||
rWrite(8,clockSel);
|
rWrite(8,clockSel);
|
||||||
|
updateSampleFreq=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PANNING: {
|
case DIV_CMD_PANNING: {
|
||||||
if (c.value==0 && c.value2==0) {
|
if (c.value==0 && c.value2==0) {
|
||||||
|
@ -317,8 +342,10 @@ void DivPlatformMSM6258::reset() {
|
||||||
msmPan=3;
|
msmPan=3;
|
||||||
rateSel=2;
|
rateSel=2;
|
||||||
clockSel=0;
|
clockSel=0;
|
||||||
|
updateSampleFreq=true;
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
|
addWrite(0xffff0001,calcVGMRate());
|
||||||
}
|
}
|
||||||
for (int i=0; i<1; i++) {
|
for (int i=0; i<1; i++) {
|
||||||
chan[i]=DivPlatformMSM6258::Channel();
|
chan[i]=DivPlatformMSM6258::Channel();
|
||||||
|
|
|
@ -50,12 +50,15 @@ class DivPlatformMSM6258: public DivDispatch {
|
||||||
|
|
||||||
unsigned char sampleBank, msmPan, msmDivider, rateSel, msmClock, clockSel;
|
unsigned char sampleBank, msmPan, msmDivider, rateSel, msmClock, clockSel;
|
||||||
signed char msmDividerCount, msmClockCount;
|
signed char msmDividerCount, msmClockCount;
|
||||||
|
bool updateSampleFreq;
|
||||||
short msmOut;
|
short msmOut;
|
||||||
|
|
||||||
int delay, updateOsc, sample, samplePos;
|
int delay, updateOsc, sample, samplePos;
|
||||||
|
|
||||||
friend void putDispatchChip(void*,int);
|
friend void putDispatchChip(void*,int);
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
|
int calcVGMRate();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
|
|
|
@ -459,7 +459,7 @@ DivMacroInt* DivPlatformSoundUnit::getChanMacroInt(int ch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short DivPlatformSoundUnit::getPan(int ch) {
|
unsigned short DivPlatformSoundUnit::getPan(int ch) {
|
||||||
return parent->convertPanLinearToSplit(chan[ch].pan^0x80,8,255);
|
return parent->convertPanLinearToSplit(chan[ch].pan+127,8,255);
|
||||||
}
|
}
|
||||||
|
|
||||||
DivDispatchOscBuffer* DivPlatformSoundUnit::getOscBuffer(int ch) {
|
DivDispatchOscBuffer* DivPlatformSoundUnit::getOscBuffer(int ch) {
|
||||||
|
|
|
@ -2205,7 +2205,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
} else if (srcPortSet==0xffd) {
|
} else if (srcPortSet==0xffd) {
|
||||||
// sample preview
|
// sample preview
|
||||||
for (size_t j=0; j<size; j++) {
|
for (size_t j=0; j<size; j++) {
|
||||||
out[destSubPort][j]+=samp_bbOut[j]/32768.0;
|
out[destSubPort][j]+=previewVol*(samp_bbOut[j]/32768.0);
|
||||||
}
|
}
|
||||||
} else if (srcPortSet==0xffe && playing && !halted) {
|
} else if (srcPortSet==0xffe && playing && !halted) {
|
||||||
// metronome
|
// metronome
|
||||||
|
|
|
@ -1137,7 +1137,7 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_PCSPKR]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_PCSPKR]=new DivSysDef(
|
||||||
"PC Speaker", NULL, 0x93, 0, 1, false, true, 0, false, 0,
|
"PC Speaker", NULL, 0x93, 0, 1, false, true, 0, false, 0,
|
||||||
"good luck!",
|
"good luck! you get one square and no volume control.",
|
||||||
{"Square"},
|
{"Square"},
|
||||||
{"SQ"},
|
{"SQ"},
|
||||||
{DIV_CH_PULSE},
|
{DIV_CH_PULSE},
|
||||||
|
@ -1146,7 +1146,7 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_PONG]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_PONG]=new DivSysDef(
|
||||||
"Pong", NULL, 0xfc, 0, 1, false, true, 0, false, 0,
|
"Pong", NULL, 0xfc, 0, 1, false, true, 0, false, 0,
|
||||||
"LOL",
|
"please don't use this chip. it was added as a joke.",
|
||||||
{"Square"},
|
{"Square"},
|
||||||
{"SQ"},
|
{"SQ"},
|
||||||
{DIV_CH_PULSE},
|
{DIV_CH_PULSE},
|
||||||
|
@ -1820,7 +1820,7 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_GA20]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_GA20]=new DivSysDef(
|
||||||
"Irem GA20", NULL, 0xc7, 0, 4, false, true, 0x171, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
"Irem GA20", NULL, 0xc7, 0, 4, false, true, 0x171, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||||
"yet another PCM chip from Irem.",
|
"yet another PCM chip from Irem. like Amiga, but less pitch resolution and no sample loop.",
|
||||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
|
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
|
||||||
{"CH1", "CH2", "CH3", "CH4"},
|
{"CH1", "CH2", "CH3", "CH4"},
|
||||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||||
|
@ -1890,7 +1890,7 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_C140]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_C140]=new DivSysDef(
|
||||||
"Namco C140", NULL, 0xce, 0, 24, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_MULAW)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
"Namco C140", NULL, 0xce, 0, 24, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_MULAW)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||||
"Namco's first PCM chip from 1987.",
|
"Namco's first PCM chip from 1987. it's pretty good for being so.",
|
||||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"},
|
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"},
|
||||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"},
|
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"},
|
||||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||||
|
@ -1901,7 +1901,7 @@ void DivEngine::registerSystems() {
|
||||||
|
|
||||||
sysDefs[DIV_SYSTEM_C219]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_C219]=new DivSysDef(
|
||||||
"Namco C219", NULL, 0xcf, 0, 16, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_C219)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
"Namco C219", NULL, 0xcf, 0, 16, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_C219)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||||
"Namco's PCM chip used in their NA-1/2 hardware.",
|
"Namco's PCM chip used in their NA-1/2 hardware.\nvery similar to C140, but has noise generator.",
|
||||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16"},
|
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16"},
|
||||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
|
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
|
||||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||||
|
|
|
@ -549,6 +549,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
w->writeC(8);
|
w->writeC(8);
|
||||||
w->writeC(0xff);
|
w->writeC(0xff);
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_MSM6258:
|
||||||
|
w->writeC(0xb8); // stop
|
||||||
|
w->writeC(baseAddr2|0);
|
||||||
|
w->writeC(1);
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_MSM6295:
|
case DIV_SYSTEM_MSM6295:
|
||||||
w->writeC(0xb8); // disable all channels
|
w->writeC(0xb8); // disable all channels
|
||||||
w->writeC(baseAddr2|0);
|
w->writeC(baseAddr2|0);
|
||||||
|
@ -1055,6 +1060,12 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
w->writeC(write.addr&0xff);
|
w->writeC(write.addr&0xff);
|
||||||
w->writeC(write.val);
|
w->writeC(write.val);
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_MSM6258:
|
||||||
|
w->writeC(0xb7);
|
||||||
|
w->writeC(baseAddr2|(write.addr&0x7f));
|
||||||
|
w->writeC(write.val);
|
||||||
|
logV("MSM write to %.2x %.2x",write.addr,write.val);
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_MSM6295:
|
case DIV_SYSTEM_MSM6295:
|
||||||
w->writeC(0xb8);
|
w->writeC(0xb8);
|
||||||
w->writeC(baseAddr2|(write.addr&0x7f));
|
w->writeC(baseAddr2|(write.addr&0x7f));
|
||||||
|
@ -1238,6 +1249,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
bool writeDACSamples=false;
|
bool writeDACSamples=false;
|
||||||
bool writeNESSamples=false;
|
bool writeNESSamples=false;
|
||||||
bool writePCESamples=false;
|
bool writePCESamples=false;
|
||||||
|
bool writeVOXSamples=false;
|
||||||
DivDispatch* writeADPCM_OPNA[2]={NULL,NULL};
|
DivDispatch* writeADPCM_OPNA[2]={NULL,NULL};
|
||||||
DivDispatch* writeADPCM_OPNB[2]={NULL,NULL};
|
DivDispatch* writeADPCM_OPNB[2]={NULL,NULL};
|
||||||
DivDispatch* writeADPCM_Y8950[2]={NULL,NULL};
|
DivDispatch* writeADPCM_Y8950[2]={NULL,NULL};
|
||||||
|
@ -1746,6 +1758,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
writeRF5C68[0]=disCont[i].dispatch;
|
writeRF5C68[0]=disCont[i].dispatch;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_MSM6258:
|
||||||
|
if (!hasOKIM6258) {
|
||||||
|
hasOKIM6258=disCont[i].dispatch->chipClock;
|
||||||
|
CHIP_VOL(23,0.65);
|
||||||
|
willExport[i]=true;
|
||||||
|
writeVOXSamples=true;
|
||||||
|
} else if (!(hasOKIM6258&0x40000000)) {
|
||||||
|
isSecond[i]=true;
|
||||||
|
CHIP_VOL_SECOND(23,0.65);
|
||||||
|
willExport[i]=true;
|
||||||
|
writeVOXSamples=true;
|
||||||
|
hasOKIM6258|=0x40000000;
|
||||||
|
howManyChips++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_MSM6295:
|
case DIV_SYSTEM_MSM6295:
|
||||||
if (!hasOKIM6295) {
|
if (!hasOKIM6295) {
|
||||||
hasOKIM6295=disCont[i].dispatch->chipClock;
|
hasOKIM6295=disCont[i].dispatch->chipClock;
|
||||||
|
@ -1927,7 +1954,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
w->writeI(hasMultiPCM);
|
w->writeI(hasMultiPCM);
|
||||||
w->writeI(hasuPD7759);
|
w->writeI(hasuPD7759);
|
||||||
w->writeI(hasOKIM6258);
|
w->writeI(hasOKIM6258);
|
||||||
w->writeC(0); // flags
|
w->writeC(hasOKIM6258?10:0); // flags
|
||||||
w->writeC(0); // K flags
|
w->writeC(0); // K flags
|
||||||
w->writeC(c140Type); // C140 chip type
|
w->writeC(c140Type); // C140 chip type
|
||||||
w->writeC(0); // reserved
|
w->writeC(0); // reserved
|
||||||
|
@ -2066,6 +2093,18 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (writeVOXSamples && !directStream) for (int i=0; i<song.sampleLen; i++) {
|
||||||
|
DivSample* sample=song.sample[i];
|
||||||
|
w->writeC(0x67);
|
||||||
|
w->writeC(0x66);
|
||||||
|
w->writeC(4);
|
||||||
|
w->writeI(sample->lengthVOX);
|
||||||
|
for (unsigned int j=0; j<sample->lengthVOX; j++) {
|
||||||
|
unsigned char actualData=(sample->dataVOX[j]>>4)|(sample->dataVOX[j]<<4);
|
||||||
|
w->writeC(actualData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
// SegaPCM
|
// SegaPCM
|
||||||
if (writeSegaPCM[i]!=NULL && writeSegaPCM[i]->getSampleMemUsage(0)>0) {
|
if (writeSegaPCM[i]!=NULL && writeSegaPCM[i]->getSampleMemUsage(0)>0) {
|
||||||
|
@ -2344,6 +2383,20 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
w->writeI(24000); // default
|
w->writeI(24000); // default
|
||||||
streamID++;
|
streamID++;
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_MSM6258:
|
||||||
|
w->writeC(0x90);
|
||||||
|
w->writeC(streamID);
|
||||||
|
w->writeC(isSecond[i]?0x97:0x17);
|
||||||
|
w->writeC(0); // port
|
||||||
|
w->writeC(1); // data input
|
||||||
|
|
||||||
|
w->writeC(0x91);
|
||||||
|
w->writeC(streamID);
|
||||||
|
w->writeC(4);
|
||||||
|
w->writeC(1);
|
||||||
|
w->writeC(0);
|
||||||
|
streamID++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1503,6 +1503,7 @@ class FurnaceGUI {
|
||||||
int separateFMColors;
|
int separateFMColors;
|
||||||
int insEditColorize;
|
int insEditColorize;
|
||||||
int metroVol;
|
int metroVol;
|
||||||
|
int sampleVol;
|
||||||
int pushNibble;
|
int pushNibble;
|
||||||
int scrollChangesOrder;
|
int scrollChangesOrder;
|
||||||
int oplStandardWaveNames;
|
int oplStandardWaveNames;
|
||||||
|
@ -1683,6 +1684,7 @@ class FurnaceGUI {
|
||||||
separateFMColors(0),
|
separateFMColors(0),
|
||||||
insEditColorize(0),
|
insEditColorize(0),
|
||||||
metroVol(100),
|
metroVol(100),
|
||||||
|
sampleVol(50),
|
||||||
pushNibble(0),
|
pushNibble(0),
|
||||||
scrollChangesOrder(0),
|
scrollChangesOrder(0),
|
||||||
oplStandardWaveNames(0),
|
oplStandardWaveNames(0),
|
||||||
|
|
|
@ -5945,6 +5945,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ins->type==DIV_INS_GA20 ||
|
ins->type==DIV_INS_GA20 ||
|
||||||
ins->type==DIV_INS_K053260 ||
|
ins->type==DIV_INS_K053260 ||
|
||||||
ins->type==DIV_INS_C140 ||
|
ins->type==DIV_INS_C140 ||
|
||||||
|
ins->type==DIV_INS_C219 ||
|
||||||
ins->type==DIV_INS_TED) {
|
ins->type==DIV_INS_TED) {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -967,7 +967,7 @@ void FurnaceGUI::drawSettings() {
|
||||||
// SUBSECTION METRONOME
|
// SUBSECTION METRONOME
|
||||||
CONFIG_SUBSECTION("Metronome");
|
CONFIG_SUBSECTION("Metronome");
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
ImGui::Text("Metronome volume");
|
ImGui::Text("Volume");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SliderInt("##MetroVol",&settings.metroVol,0,200,"%d%%")) {
|
if (ImGui::SliderInt("##MetroVol",&settings.metroVol,0,200,"%d%%")) {
|
||||||
if (settings.metroVol<0) settings.metroVol=0;
|
if (settings.metroVol<0) settings.metroVol=0;
|
||||||
|
@ -975,6 +975,17 @@ void FurnaceGUI::drawSettings() {
|
||||||
e->setMetronomeVol(((float)settings.metroVol)/100.0f);
|
e->setMetronomeVol(((float)settings.metroVol)/100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SUBSECTION SAMPLE PREVIEW
|
||||||
|
CONFIG_SUBSECTION("Sample preview");
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
ImGui::Text("Volume");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::SliderInt("##SampleVol",&settings.sampleVol,0,100,"%d%%")) {
|
||||||
|
if (settings.sampleVol<0) settings.sampleVol=0;
|
||||||
|
if (settings.sampleVol>100) settings.sampleVol=100;
|
||||||
|
e->setSamplePreviewVol(((float)settings.sampleVol)/100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
END_SECTION;
|
END_SECTION;
|
||||||
}
|
}
|
||||||
CONFIG_SECTION("MIDI") {
|
CONFIG_SECTION("MIDI") {
|
||||||
|
@ -3246,6 +3257,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.separateFMColors=e->getConfInt("separateFMColors",0);
|
settings.separateFMColors=e->getConfInt("separateFMColors",0);
|
||||||
settings.insEditColorize=e->getConfInt("insEditColorize",0);
|
settings.insEditColorize=e->getConfInt("insEditColorize",0);
|
||||||
settings.metroVol=e->getConfInt("metroVol",100);
|
settings.metroVol=e->getConfInt("metroVol",100);
|
||||||
|
settings.sampleVol=e->getConfInt("sampleVol",50);
|
||||||
settings.pushNibble=e->getConfInt("pushNibble",0);
|
settings.pushNibble=e->getConfInt("pushNibble",0);
|
||||||
settings.scrollChangesOrder=e->getConfInt("scrollChangesOrder",0);
|
settings.scrollChangesOrder=e->getConfInt("scrollChangesOrder",0);
|
||||||
settings.oplStandardWaveNames=e->getConfInt("oplStandardWaveNames",0);
|
settings.oplStandardWaveNames=e->getConfInt("oplStandardWaveNames",0);
|
||||||
|
@ -3407,6 +3419,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.separateFMColors,0,1);
|
clampSetting(settings.separateFMColors,0,1);
|
||||||
clampSetting(settings.insEditColorize,0,1);
|
clampSetting(settings.insEditColorize,0,1);
|
||||||
clampSetting(settings.metroVol,0,200);
|
clampSetting(settings.metroVol,0,200);
|
||||||
|
clampSetting(settings.sampleVol,0,100);
|
||||||
clampSetting(settings.pushNibble,0,1);
|
clampSetting(settings.pushNibble,0,1);
|
||||||
clampSetting(settings.scrollChangesOrder,0,2);
|
clampSetting(settings.scrollChangesOrder,0,2);
|
||||||
clampSetting(settings.oplStandardWaveNames,0,1);
|
clampSetting(settings.oplStandardWaveNames,0,1);
|
||||||
|
@ -3535,6 +3548,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
|
|
||||||
e->setMidiDirect(midiMap.directChannel);
|
e->setMidiDirect(midiMap.directChannel);
|
||||||
e->setMetronomeVol(((float)settings.metroVol)/100.0f);
|
e->setMetronomeVol(((float)settings.metroVol)/100.0f);
|
||||||
|
e->setSamplePreviewVol(((float)settings.sampleVol)/100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FurnaceGUI::commitSettings() {
|
void FurnaceGUI::commitSettings() {
|
||||||
|
@ -3656,6 +3670,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("separateFMColors",settings.separateFMColors);
|
e->setConf("separateFMColors",settings.separateFMColors);
|
||||||
e->setConf("insEditColorize",settings.insEditColorize);
|
e->setConf("insEditColorize",settings.insEditColorize);
|
||||||
e->setConf("metroVol",settings.metroVol);
|
e->setConf("metroVol",settings.metroVol);
|
||||||
|
e->setConf("sampleVol",settings.sampleVol);
|
||||||
e->setConf("pushNibble",settings.pushNibble);
|
e->setConf("pushNibble",settings.pushNibble);
|
||||||
e->setConf("scrollChangesOrder",settings.scrollChangesOrder);
|
e->setConf("scrollChangesOrder",settings.scrollChangesOrder);
|
||||||
e->setConf("oplStandardWaveNames",settings.oplStandardWaveNames);
|
e->setConf("oplStandardWaveNames",settings.oplStandardWaveNames);
|
||||||
|
|
|
@ -1338,6 +1338,64 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
||||||
altered=true;
|
altered=true;
|
||||||
}
|
}
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
int chipClock=flags.getInt("customClock",0);
|
||||||
|
if (!chipClock) {
|
||||||
|
switch (clockSel) {
|
||||||
|
case 0:
|
||||||
|
chipClock=4000000;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
chipClock=4096000;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
chipClock=8000000;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
chipClock=8192000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Sample rate table:");
|
||||||
|
if (ImGui::BeginTable("6258Rate",3)) {
|
||||||
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("divider \\ clock");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("full");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("half");
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
|
||||||
|
ImGui::Text("/512");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/512);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/1024);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
|
||||||
|
ImGui::Text("/768");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/768);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/1536);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
|
||||||
|
ImGui::Text("/1024");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/1024);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%dHz",chipClock/2048);
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
e->lockSave([&]() {
|
e->lockSave([&]() {
|
||||||
|
|
Loading…
Reference in a new issue