Merge branch 'master' into exportwin
4
.github/workflows/build.yml
vendored
|
@ -22,8 +22,8 @@ jobs:
|
||||||
- { name: 'Windows MSVC x86_64', os: windows-latest, compiler: msvc, arch: x86_64 }
|
- { name: 'Windows MSVC x86_64', os: windows-latest, compiler: msvc, arch: x86_64 }
|
||||||
#- { name: 'Windows MinGW x86', os: ubuntu-20.04, compiler: mingw, arch: x86 }
|
#- { name: 'Windows MinGW x86', os: ubuntu-20.04, compiler: mingw, arch: x86 }
|
||||||
#- { name: 'Windows MinGW x86_64', os: ubuntu-20.04, compiler: mingw, arch: x86_64 }
|
#- { name: 'Windows MinGW x86_64', os: ubuntu-20.04, compiler: mingw, arch: x86_64 }
|
||||||
- { name: 'macOS x86_64', os: macos-latest, arch: x86_64 }
|
#- { name: 'macOS x86_64', os: macos-latest, arch: x86_64 }
|
||||||
- { name: 'macOS ARM', os: macos-latest, arch: arm64 }
|
#- { name: 'macOS ARM', os: macos-latest, arch: arm64 }
|
||||||
- { name: 'Linux x86_64', os: ubuntu-20.04, arch: x86_64 }
|
- { name: 'Linux x86_64', os: ubuntu-20.04, arch: x86_64 }
|
||||||
#- { name: 'Linux ARM', os: ubuntu-18.04, arch: armhf }
|
#- { name: 'Linux ARM', os: ubuntu-18.04, arch: armhf }
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
|
@ -35,6 +35,7 @@ the coding style is described here:
|
||||||
- preprocessor directives not intended
|
- preprocessor directives not intended
|
||||||
- if macro comprises more than one line, indent
|
- if macro comprises more than one line, indent
|
||||||
- no new line after `template<>`
|
- no new line after `template<>`
|
||||||
|
- do not use `_t` types, except for 64-bit integers and `size_t`.
|
||||||
- prefer built-in types:
|
- prefer built-in types:
|
||||||
- `bool`
|
- `bool`
|
||||||
- `signed char` or `unsigned char` are 8-bit
|
- `signed char` or `unsigned char` are 8-bit
|
||||||
|
@ -48,6 +49,7 @@ the coding style is described here:
|
||||||
- `long long int` or `unsigned long long int` are 64-bit
|
- `long long int` or `unsigned long long int` are 64-bit
|
||||||
- avoid using 64-bit numbers as I still build for 32-bit systems.
|
- avoid using 64-bit numbers as I still build for 32-bit systems.
|
||||||
- two `long`s are required to make Windows happy.
|
- two `long`s are required to make Windows happy.
|
||||||
|
- prefer using `int64_t` or `uint64_t` for this specific case.
|
||||||
- `size_t` are 32-bit or 64-bit, depending on architecture.
|
- `size_t` are 32-bit or 64-bit, depending on architecture.
|
||||||
- in float/double operations, always use decimal and `f` if single-precision.
|
- in float/double operations, always use decimal and `f` if single-precision.
|
||||||
- e.g. `1.0f` or `1.0` instead of `1`.
|
- e.g. `1.0f` or `1.0` instead of `1`.
|
||||||
|
|
4
TODO.md
|
@ -4,11 +4,9 @@
|
||||||
|
|
||||||
# THE REAL TO-DO LIST
|
# THE REAL TO-DO LIST
|
||||||
|
|
||||||
- Song is silent after playing an order after loop point
|
|
||||||
- Select loaded instrument on open - rewrite because I want a setting...
|
|
||||||
- finish auto-clone
|
- finish auto-clone
|
||||||
|
|
||||||
once you have done all of this (maybe not the first one) and merged the two or so pending pull requests, release 0.6.1
|
once you have done all of this (maybe not the first one), release 0.6.1
|
||||||
|
|
||||||
Furnace is like alcohol...
|
Furnace is like alcohol...
|
||||||
|
|
||||||
|
|
BIN
demos/misc/waterworld_map_opm.fur
Normal file
BIN
demos/multichip/second_dimension_demo.fur
Normal file
BIN
demos/multichip/urgency.fur
Normal file
BIN
demos/sn7/456nm_TI994A.fur
Normal file
BIN
demos/snes/Unreal_Something_SNES.fur
Normal file
BIN
demos/virtualboy/4_dimensionnal_goddess_of_existance.fur
Normal file
BIN
demos/virtualboy/Cherry_Vertex.fur
Normal file
BIN
demos/virtualboy/Double_Puzzle_Trouble.fur
Normal file
BIN
demos/virtualboy/DoublingDown.fur
Normal file
BIN
demos/virtualboy/LN2StreetLoader-VB.fur
Normal file
BIN
demos/virtualboy/No_Such_Thing.fur
Normal file
BIN
demos/virtualboy/Red_And_Black_Orchid.fur
Normal file
BIN
demos/x68000/Optimistic.fur
Normal file
BIN
doc/2-interface/MIDI-value-input-1.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
doc/2-interface/MIDI-value-input-2.png
Normal file
After Width: | Height: | Size: 39 KiB |
|
@ -35,6 +35,7 @@ items in _italic_ don't appear in basic mode and are only available in advanced
|
||||||
|
|
||||||
- **export audio...**: opens the file picker, allowing you to export your song to a .wav file. see next section for more details.
|
- **export audio...**: opens the file picker, allowing you to export your song to a .wav file. see next section for more details.
|
||||||
- **export VGM...**: opens the file picker, allowing you to export your song to a .vgm file. see next section for more details.
|
- **export VGM...**: opens the file picker, allowing you to export your song to a .vgm file. see next section for more details.
|
||||||
|
- **export text...**: opens the file picker, allowing you to export your song to a .txt file.
|
||||||
- **export ZSM...**: opens the file picker, allowing you to export your song to a .zsm file. see next section for more details.
|
- **export ZSM...**: opens the file picker, allowing you to export your song to a .zsm file. see next section for more details.
|
||||||
- only available when there's a YM2151 and/or VERA.
|
- only available when there's a YM2151 and/or VERA.
|
||||||
- **export command stream...**: export song data to a command stream file. see next section for more details.
|
- **export command stream...**: export song data to a command stream file. see next section for more details.
|
||||||
|
@ -140,6 +141,7 @@ it's not really useful, unless you're a developer and want to use a command stre
|
||||||
- **cut**: moves the current selection in the pattern view to clipboard.
|
- **cut**: moves the current selection in the pattern view to clipboard.
|
||||||
- **copy**: copies the current selection in the pattern view to clipboard.
|
- **copy**: copies the current selection in the pattern view to clipboard.
|
||||||
- **paste**: inserts the clipboard's contents in the cursor position.
|
- **paste**: inserts the clipboard's contents in the cursor position.
|
||||||
|
- you may be able to paste from OpenMPT as well.
|
||||||
- _**paste special...**:_ variants of the paste feature.
|
- _**paste special...**:_ variants of the paste feature.
|
||||||
- **paste mix**: inserts the clipboard's contents in the cursor position, but does not erase the occupied region.
|
- **paste mix**: inserts the clipboard's contents in the cursor position, but does not erase the occupied region.
|
||||||
- **paste mix (background)**: does the same thing as paste mix, but doesn't alter content which is already there.
|
- **paste mix (background)**: does the same thing as paste mix, but doesn't alter content which is already there.
|
||||||
|
|
|
@ -123,22 +123,21 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
|
||||||
- **Note input**: enables note input. disable if you intend to use this device only for binding actions.
|
- **Note input**: enables note input. disable if you intend to use this device only for binding actions.
|
||||||
- **Velocity input**: enables velocity input when entering notes in the pattern.
|
- **Velocity input**: enables velocity input when entering notes in the pattern.
|
||||||
- **Map MIDI channels to direct channels**: when enabled, notes from MIDI channels will be mapped to channels rather than the cursor position.
|
- **Map MIDI channels to direct channels**: when enabled, notes from MIDI channels will be mapped to channels rather than the cursor position.
|
||||||
|
- **Program change pass-through**: when enabled, program change events are sent to each channel as instrument change commands.
|
||||||
|
- this option is only available when the previous one is enabled.
|
||||||
- **Map Yamaha FM voice data to instruments**: when enabled, Furnace will listen for any transmitted Yamaha SysEx patches.
|
- **Map Yamaha FM voice data to instruments**: when enabled, Furnace will listen for any transmitted Yamaha SysEx patches.
|
||||||
- this option is only useful if you have a Yamaha FM synthesizer (e.g. TX81Z).
|
- this option is only useful if you have a Yamaha FM synthesizer (e.g. TX81Z).
|
||||||
- selecting a voice or using the "Voice Transmit?" option will send a patch, and Furnace will create a new instrument with its data.
|
- selecting a voice or using the "Voice Transmit?" option will send a patch, and Furnace will create a new instrument with its data.
|
||||||
- this may also be triggered by clicking on "Receive from TX81Z" in the instrument editor (OPZ only).
|
- this may also be triggered by clicking on "Receive from TX81Z" in the instrument editor (OPZ only).
|
||||||
- **Program change is instrument selection**: changes the current instrument when a program change event is received.
|
- **Program change is instrument selection**: changes the current instrument when a program change event is received.
|
||||||
|
- this option is not available when "Program change pass-through" is enabled.
|
||||||
- **Value input style**: changes the way values are entered when the pattern cursor is not in the Note column. the following styles are available:
|
- **Value input style**: changes the way values are entered when the pattern cursor is not in the Note column. the following styles are available:
|
||||||
- **Disabled/custom**: no value input through MIDI.
|
- **Disabled/custom**: no value input through MIDI.
|
||||||
- **Two octaves (0 is C-4, F is D#5)**: maps keys in two octaves to single nibble input. the layout is:
|
- **Two octaves (0 is C-4, F is D#5)**: maps keys in two octaves to single nibble input. the layout is:
|
||||||
- ` - octave n -- octave n+1 -`
|

|
||||||
- ` 1 3 6 8 A D F # # # `
|
|
||||||
- `0 2 4 5 7 9 B C E # # # # #`
|
|
||||||
- **Raw (note number is value)**: the note number becomes the input value. not useful if you want to input anything above 7F.
|
- **Raw (note number is value)**: the note number becomes the input value. not useful if you want to input anything above 7F.
|
||||||
- **Two octaves alternate (lower keys are 0-9, upper keys are A-F)**: maps keys in two octaves, but with a different layout:
|
- **Two octaves alternate (lower keys are 0-9, upper keys are A-F)**: maps keys in two octaves, but with a different layout:
|
||||||
- ` - octave n -- octave n+1 -`
|

|
||||||
- ` A B C D E F # # # # `
|
|
||||||
- `0 1 2 3 4 5 6 7 8 9 # # # #`
|
|
||||||
- **Use dual control change (one for each nibble)**: maps two control change events to the nibbles of a value.
|
- **Use dual control change (one for each nibble)**: maps two control change events to the nibbles of a value.
|
||||||
- **CC of upper nibble**: select the CC number that will change the upper nibble.
|
- **CC of upper nibble**: select the CC number that will change the upper nibble.
|
||||||
- **CC of lower nibble**: select the CC number that will change the lower nibble.
|
- **CC of lower nibble**: select the CC number that will change the lower nibble.
|
||||||
|
@ -149,6 +148,7 @@ settings are saved when clicking the **OK** or **Apply** buttons at the bottom o
|
||||||
- **Control**: select the CC number that will change the value.
|
- **Control**: select the CC number that will change the value.
|
||||||
- **Per-column control change**: when enabled, you can map several control change events to a channel's columns.
|
- **Per-column control change**: when enabled, you can map several control change events to a channel's columns.
|
||||||
- **Volume curve**: adjust the velocity to volume curve.
|
- **Volume curve**: adjust the velocity to volume curve.
|
||||||
|
- the default is 2.0, which matches General MIDI standard.
|
||||||
- **Actions**: this allows you to bind note input and control change events to actions.
|
- **Actions**: this allows you to bind note input and control change events to actions.
|
||||||
- **`+`** button: adds a new action.
|
- **`+`** button: adds a new action.
|
||||||
- window-with-arrow button: new action with learning! press a button or move a slider/knob/something on your device.
|
- window-with-arrow button: new action with learning! press a button or move a slider/knob/something on your device.
|
||||||
|
@ -305,6 +305,12 @@ below all the binds, select a key from the dropdown list to add it. it will appe
|
||||||
- **Yes**
|
- **Yes**
|
||||||
- **Inverted**
|
- **Inverted**
|
||||||
|
|
||||||
|
### Assets
|
||||||
|
|
||||||
|
- **Display instrument type menu when adding instrument**
|
||||||
|
- if turned off, the menu can still be opened by right-clicking the add button.
|
||||||
|
- **Select asset after opening one**
|
||||||
|
|
||||||
## Appearance
|
## Appearance
|
||||||
|
|
||||||
### Scaling
|
### Scaling
|
||||||
|
@ -435,8 +441,6 @@ below all the binds, select a key from the dropdown list to add it. it will appe
|
||||||
- **Graphical icons**
|
- **Graphical icons**
|
||||||
- **Letter icons**
|
- **Letter icons**
|
||||||
- **Colorize instrument editor using instrument type**
|
- **Colorize instrument editor using instrument type**
|
||||||
- **Display instrument type menu when adding instrument**
|
|
||||||
- if turned off, the menu can still be opened by right-clicking the add button.
|
|
||||||
|
|
||||||
### Macro Editor
|
### Macro Editor
|
||||||
|
|
||||||
|
@ -494,7 +498,7 @@ below all the binds, select a key from the dropdown list to add it. it will appe
|
||||||
- **Rounded window corners**
|
- **Rounded window corners**
|
||||||
- **Rounded buttons**
|
- **Rounded buttons**
|
||||||
- **Rounded menu corners**
|
- **Rounded menu corners**
|
||||||
- **Borders around widgets**: draws thin borders on buttons, checkboxes, text widgets, and the like.
|
- **Borders around widgets**: draws borders on buttons, checkboxes, text widgets, and the like.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -505,6 +509,7 @@ below all the binds, select a key from the dropdown list to add it. it will appe
|
||||||
- **Import**
|
- **Import**
|
||||||
- **Export**
|
- **Export**
|
||||||
- **Reset defaults**
|
- **Reset defaults**
|
||||||
|
- **Guru mode**: exposes all color options (instead of accent colors).
|
||||||
- **General**
|
- **General**
|
||||||
- **Color scheme type:**
|
- **Color scheme type:**
|
||||||
- **Dark**
|
- **Dark**
|
||||||
|
|
|
@ -126,14 +126,25 @@ finally, the sequence of values can be directly edited in the text box at the bo
|
||||||
- in arpeggio macros, a value starting with a `@` is a fixed value as described above.
|
- in arpeggio macros, a value starting with a `@` is a fixed value as described above.
|
||||||
- in bitmask-style macros, the values are added up in binary and converted to decimal. see [the hexadecimal guide](../1-intro/hex.md) for more info.
|
- in bitmask-style macros, the values are added up in binary and converted to decimal. see [the hexadecimal guide](../1-intro/hex.md) for more info.
|
||||||
|
|
||||||
|
in all cases except bitmask macros, right-clicking on the graph opens up an editing menu:
|
||||||
|
- **copy**: copies the macro.
|
||||||
|
- **paste**: pastes the macro in the clipboard.
|
||||||
|
- **clear**: clears the macro.
|
||||||
|
- **clear contents**: resets all values to 0.
|
||||||
|
- **offset**:
|
||||||
|
- **X**: slides the data "horizontally" within the macro, filling the gap with zeroes. data moved past the start or end is lost.
|
||||||
|
- **Y**: increases or decreases all values, clipping them if they would move past the allowed range.
|
||||||
|
- **scale**:
|
||||||
|
- **X**: stretches the macro.
|
||||||
|
- **Y**: multiplies all values by the scale factor, clipping them if they would exceed the allowed range.
|
||||||
|
- **randomize**: replaces all values with random values between **Min** and **Max**.
|
||||||
|
|
||||||
### ADSR
|
### ADSR
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- **Bottom** and **Top** determine the range of outputs generated by the macro. (Bottom can be larger than Top to invert the envelope!) All outputs will be between these two values.
|
- **Bottom** and **Top** determine the range of outputs generated by the macro. (Bottom can be larger than Top to invert the envelope!) All outputs will be between these two values.
|
||||||
- attack, Decay, Sustain, SusDecay, and Release accept inputs between 0 to 255. these are scaled to the distance between Bottom and Top.
|
- Attack, Decay, Sustain, SusDecay, and Release accept inputs between 0 to 255. these are scaled to the distance between Bottom and Top.
|
||||||
- **Attack** is how much the value moves toward Top with each tick.
|
- **Attack** is how much the value moves toward Top with each tick.
|
||||||
- **Hold** sets how many ticks to stay at Top before Decay.
|
- **Hold** sets how many ticks to stay at Top before Decay.
|
||||||
- **Decay** is how much the value moves to the Sustain level.
|
- **Decay** is how much the value moves to the Sustain level.
|
||||||
|
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 627 B After Width: | Height: | Size: 869 B |
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 795 B |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB |
|
@ -154,6 +154,9 @@ in there, you can modify certain data pertaining to your sample, such as the:
|
||||||
- **Low-pass**: amount to attenuate everything above cutoff.
|
- **Low-pass**: amount to attenuate everything above cutoff.
|
||||||
- **Band-pass**: amount to attenuate everything outside cutoff.
|
- **Band-pass**: amount to attenuate everything outside cutoff.
|
||||||
- **High-pass**: amount to attenuate everything below cutoff.
|
- **High-pass**: amount to attenuate everything below cutoff.
|
||||||
|
- **Crossfade loop points**: applies a "fade" between the loop's starting point and the end.
|
||||||
|
- **Number of samples**: how many samples in the loop region to take into account for crossfade.
|
||||||
|
- **Linear <-> Equal power**: the curve used to crossfade.
|
||||||
- **Preview sample**: plays sample at base frequency.
|
- **Preview sample**: plays sample at base frequency.
|
||||||
- **Stop sample preview**: stops preview.
|
- **Stop sample preview**: stops preview.
|
||||||
- **Create instrument from sample**: creates a new instrument with its sample set to the current sample.
|
- **Create instrument from sample**: creates a new instrument with its sample set to the current sample.
|
||||||
|
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 202 KiB |
|
@ -6,7 +6,7 @@ it has 256 nibbles (128 bytes) of internal RAM which is shared between channel s
|
||||||
|
|
||||||
wavetables are variable in size and may be allocated anywhere in RAM. at least 128 nibbles (64 bytes) can be dedicated to waves, with more available if not all channels are used - waveform RAM area becomes smaller as more channels are activated, since channel registers consume 8 bytes for each channel.
|
wavetables are variable in size and may be allocated anywhere in RAM. at least 128 nibbles (64 bytes) can be dedicated to waves, with more available if not all channels are used - waveform RAM area becomes smaller as more channels are activated, since channel registers consume 8 bytes for each channel.
|
||||||
|
|
||||||
Namco 163 uses time-division multiplexing for its output. this means that only one channel is output per sample (like OPLL and OPN2). therefore, its sound quality gets worse as more channels are activated.
|
Namco 163 uses time-division multiplexing (TDM) for its output. this means that only one channel is output per sample (like OPLL and OPN2). therefore, its sound quality gets worse as more channels are activated.
|
||||||
|
|
||||||
## waveform load position versus waveform position
|
## waveform load position versus waveform position
|
||||||
|
|
||||||
|
@ -39,6 +39,13 @@ if the waveform changes (e.g. ins change, wave macro or wave synth), or the **lo
|
||||||
- make sure to use `21xx` first!
|
- make sure to use `21xx` first!
|
||||||
- `21xx`: **set position for 20xx.**
|
- `21xx`: **set position for 20xx.**
|
||||||
|
|
||||||
|
## chip options
|
||||||
|
|
||||||
|
- **Initial channel limit**: sets the number of channels that will be active. higher values reduce volume and make TDM artifacts more noticeable.
|
||||||
|
- **Disable hissing**: remove TDM artifacts by mixing. sacrifices some accuracy!
|
||||||
|
- **Scale frequency to wave length**: automatically adjusts note frequency to account for differing waveform lengths.
|
||||||
|
- if disabled, note frequencies ignore waveveform length. this is how FamiTracker behaves.
|
||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [Namco 163](../4-instrument/n163.md) instrument editor.
|
this chip uses the [Namco 163](../4-instrument/n163.md) instrument editor.
|
||||||
|
|
|
@ -82,3 +82,5 @@ afterwards everyone moved to Windows and software mixed PCM streaming...
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [FM (OPL)](../4-instrument/fm-opl.md) instrument editor.
|
this chip uses the [FM (OPL)](../4-instrument/fm-opl.md) instrument editor.
|
||||||
|
|
||||||
|
when two channels are joined for 4-op mode, the channel bar will show `4OP` on a bracket tying them together.
|
|
@ -15,8 +15,8 @@ the YM2413 is equipped with the following features:
|
||||||
- a drum/percussion mode, replacing the last 3 voices with 5 rhythm channels, with drum mode tones hard-defined in the chip itself, like FM instruments. only pitch might be altered.
|
- a drum/percussion mode, replacing the last 3 voices with 5 rhythm channels, with drum mode tones hard-defined in the chip itself, like FM instruments. only pitch might be altered.
|
||||||
- drum mode works like following: FM channel 7 is for Kick Drum, which is a normal FM channel but routed through mixer twice for 2× volume, like all drum sounds. FM channel 8 splits to Snare, Drum, and Hi-Hat. Snare Drum is the carrier and it works with a special 1 bit noise generator combined with a square wave, all possible by overriding phase-generator with some different synthesis method. Hi-Hat is the modulator and it works with the noise generator and also the special synthesis. channel 9 splits to Top-Cymbal and Tom-Tom, Top-Cymbal is the carrier and only has the special synthesis, while Tom-Tom is basically a 1op wave.
|
- drum mode works like following: FM channel 7 is for Kick Drum, which is a normal FM channel but routed through mixer twice for 2× volume, like all drum sounds. FM channel 8 splits to Snare, Drum, and Hi-Hat. Snare Drum is the carrier and it works with a special 1 bit noise generator combined with a square wave, all possible by overriding phase-generator with some different synthesis method. Hi-Hat is the modulator and it works with the noise generator and also the special synthesis. channel 9 splits to Top-Cymbal and Tom-Tom, Top-Cymbal is the carrier and only has the special synthesis, while Tom-Tom is basically a 1op wave.
|
||||||
- special synthesis mentioned already is: 5 square waves are gathered from 4×, 64× and 128× the pitch of channel 8 and 16× and 64× the pitch of channel 9 and they go through a process where 2 HH bits OR'd together, then 1 HH and 1 TC bit OR'd, then the two TC bits OR'd together, and those 3 results get XOR'd.
|
- special synthesis mentioned already is: 5 square waves are gathered from 4×, 64× and 128× the pitch of channel 8 and 16× and 64× the pitch of channel 9 and they go through a process where 2 HH bits OR'd together, then 1 HH and 1 TC bit OR'd, then the two TC bits OR'd together, and those 3 results get XOR'd.
|
||||||
- 1 user-definable patch (this patch can be changed throughout the course of the song)
|
- **1 user-definable patch (this patch can be changed throughout the course of the song)**
|
||||||
- 15 pre-defined patches which can all be used at the same time
|
- **15 pre-defined patches which can all be used at the same time**
|
||||||
- support for ADSR on both the modulator and the carrier
|
- support for ADSR on both the modulator and the carrier
|
||||||
- sine and half-sine based FM synthesis
|
- sine and half-sine based FM synthesis
|
||||||
- 9 octave note control
|
- 9 octave note control
|
||||||
|
|
|
@ -39,3 +39,7 @@ a sound and input chip developed by Atari for their 8-bit computers (Atari 400,
|
||||||
## info
|
## info
|
||||||
|
|
||||||
this chip uses the [POKEY](../4-instrument/pokey.md) instrument editor.
|
this chip uses the [POKEY](../4-instrument/pokey.md) instrument editor.
|
||||||
|
|
||||||
|
when two channels are joined for filtered output, the channel bar will show `filter` on a bracket tying them together.
|
||||||
|
|
||||||
|
when two channels are joined for wide period range, the channel bar will show `16-bit` on a bracket tying them together.
|
||||||
|
|
|
@ -65,6 +65,8 @@ Furnace also allows the SNES to use wavetables (and the wavetable synthesizer) i
|
||||||
|
|
||||||
this chip uses the [SNES](../4-instrument/snes.md) instrument editor.
|
this chip uses the [SNES](../4-instrument/snes.md) instrument editor.
|
||||||
|
|
||||||
|
when two channels are joined for pitch modulation, the channel bar will show `mod` on a bracket tying them together.
|
||||||
|
|
||||||
## channel status
|
## channel status
|
||||||
|
|
||||||
the following icons are displayed when channel status is enabled in the pattern view:
|
the following icons are displayed when channel status is enabled in the pattern view:
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# guides
|
# guides
|
||||||
|
|
||||||
this is collection of user-contributed Furnace guides which may be useful during composition.
|
this is a collection of user-contributed Furnace guides which may be useful during composition.
|
||||||
|
|
||||||
|
- [tuning samples](tuning-samples.md)
|
||||||
- [using samples with limited playback rates](limited-samples.md)
|
- [using samples with limited playback rates](limited-samples.md)
|
||||||
- [choosing emulation cores](emulation-cores.md)
|
- [choosing emulation cores](emulation-cores.md)
|
||||||
- [using OPLL patch macro](opllswitching.md)
|
- [using OPLL patch macro](opllswitching.md)
|
||||||
|
|
16
doc/9-guides/tuning-samples.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# tuning samples
|
||||||
|
|
||||||
|
loading a new sample into Furnace is easy... but getting it transposed and tuned to match the song can be tricky at first.
|
||||||
|
|
||||||
|
it's important to remember that the "Hz" and "Note" as shown in the sample editor are unrelated to the note heard in the sample itself. a sample shown as having a "Note" of C-4 will use a sample rate of 4181, even though it may contain a note played at a different pitch than C.
|
||||||
|
|
||||||
|
for this example, we'll use a sample of a note played at E and recorded at 22050Hz.
|
||||||
|
|
||||||
|
- if needed, use the "Create instrument from sample" button to make an instrument to use in the track.
|
||||||
|
- calculate the semitone difference in Hz between the note your recorded sample is playing and C. in this example, the nearest C is 4 semitones down from E.
|
||||||
|
- set "Note" to 4 semitones lower than it shows. in this case, it starts at `F-6`, so set it to `C#6`.
|
||||||
|
- or, use a pitch calculator like https://www.omnicalculator.com/other/semitone. input Frequency 1 as 22050Hz, input -4 semitones, and receive a Frequency 2 of 17501.10Hz. enter that value into "Hz".
|
||||||
|
- now, using the "Preview sample" button should play the note at C. entering an E in the pattern will now play it at or near E.
|
||||||
|
- if the sample still sounds out of tune, adjust "Hz" or "Fine" to bring it in line.
|
||||||
|
|
||||||
|
if notes seem "capped" – for example, playing anything over D-6 sounds like a D-6 – those notes exceed the maximum sample playback rate for the chip. the only solution is to use "Resample" to change the sample to a lower rate.
|
|
@ -23,7 +23,6 @@ the index follows.
|
||||||
- freq-mod
|
- freq-mod
|
||||||
- host12prog
|
- host12prog
|
||||||
- Lunathir
|
- Lunathir
|
||||||
- nicco1690
|
|
||||||
- tildearrow
|
- tildearrow
|
||||||
|
|
||||||
## information
|
## information
|
||||||
|
|
BIN
instruments/OPN/keys/Acoustic E-Piano.fui
Normal file
|
@ -18,7 +18,6 @@ these are organized in the respective chip folders.
|
||||||
- jvsTSX
|
- jvsTSX
|
||||||
- Laggy
|
- Laggy
|
||||||
- LovelyA72
|
- LovelyA72
|
||||||
- nicco1690
|
|
||||||
- PacorexTheTrex
|
- PacorexTheTrex
|
||||||
- paynspch
|
- paynspch
|
||||||
- pedipanol
|
- pedipanol
|
||||||
|
|
|
@ -363,7 +363,8 @@ size | description
|
||||||
1 | pre note (C64) does not compensate for portamento or legato (>=168)
|
1 | pre note (C64) does not compensate for portamento or legato (>=168)
|
||||||
1 | disable new NES DPCM features (>=183)
|
1 | disable new NES DPCM features (>=183)
|
||||||
1 | reset arp effect phase on new note (>=184)
|
1 | reset arp effect phase on new note (>=184)
|
||||||
3 | reserved
|
1 | linear volume scaling rounds up (>=188)
|
||||||
|
2 | reserved
|
||||||
--- | **speed pattern of first song** (>=139)
|
--- | **speed pattern of first song** (>=139)
|
||||||
1 | length of speed pattern (fail if this is lower than 0 or higher than 16)
|
1 | length of speed pattern (fail if this is lower than 0 or higher than 16)
|
||||||
16 | speed pattern (this overrides speed 1 and speed 2 settings)
|
16 | speed pattern (this overrides speed 1 and speed 2 settings)
|
||||||
|
|
|
@ -341,7 +341,6 @@ if __name__ == "__main__":
|
||||||
<li>freq-mod</li>
|
<li>freq-mod</li>
|
||||||
<li>host12prog</li>
|
<li>host12prog</li>
|
||||||
<li>Lunathir</li>
|
<li>Lunathir</li>
|
||||||
<li>nicco1690</li>
|
|
||||||
<li>tildearrow</li>
|
<li>tildearrow</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>special thanks to ZoomTen for providing tools which assisted in the production of this document!</p>
|
<p>special thanks to ZoomTen for providing tools which assisted in the production of this document!</p>
|
||||||
|
|
415
res/icons.sfd
|
@ -21,7 +21,7 @@ OS2Version: 0
|
||||||
OS2_WeightWidthSlopeOnly: 0
|
OS2_WeightWidthSlopeOnly: 0
|
||||||
OS2_UseTypoMetrics: 0
|
OS2_UseTypoMetrics: 0
|
||||||
CreationTime: 1691897631
|
CreationTime: 1691897631
|
||||||
ModificationTime: 1698523374
|
ModificationTime: 1701817435
|
||||||
PfmFamily: 81
|
PfmFamily: 81
|
||||||
TTFWeight: 400
|
TTFWeight: 400
|
||||||
TTFWidth: 5
|
TTFWidth: 5
|
||||||
|
@ -47,13 +47,13 @@ LangName: 1033
|
||||||
Encoding: UnicodeBmp
|
Encoding: UnicodeBmp
|
||||||
UnicodeInterp: none
|
UnicodeInterp: none
|
||||||
NameList: AGL For New Fonts
|
NameList: AGL For New Fonts
|
||||||
DisplaySize: -24
|
DisplaySize: -96
|
||||||
AntiAlias: 1
|
AntiAlias: 1
|
||||||
FitToEm: 0
|
FitToEm: 0
|
||||||
WinInfo: 57552 16 10
|
WinInfo: 57672 8 5
|
||||||
BeginPrivate: 0
|
BeginPrivate: 0
|
||||||
EndPrivate
|
EndPrivate
|
||||||
BeginChars: 65536 95
|
BeginChars: 65536 96
|
||||||
|
|
||||||
StartChar: space
|
StartChar: space
|
||||||
Encoding: 32 32 0
|
Encoding: 32 32 0
|
||||||
|
@ -6732,5 +6732,412 @@ SplineSet
|
||||||
1595 691.666666667 1611.33333333 700 1632 700 c 0
|
1595 691.666666667 1611.33333333 700 1632 700 c 0
|
||||||
EndSplineSet
|
EndSplineSet
|
||||||
EndChar
|
EndChar
|
||||||
|
|
||||||
|
StartChar: uniE159
|
||||||
|
Encoding: 57689 57689 95
|
||||||
|
Width: 1792
|
||||||
|
Flags: HWO
|
||||||
|
LayerCount: 2
|
||||||
|
UndoRedoHistory
|
||||||
|
Layer: 0
|
||||||
|
Undoes
|
||||||
|
UndoOperation
|
||||||
|
Index: 0
|
||||||
|
Type: 1
|
||||||
|
WasModified: 0
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 1
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
1632 70 m 1
|
||||||
|
1632 -50 l 1025
|
||||||
|
160 1210 m 1
|
||||||
|
160 1330 l 1025
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 1
|
||||||
|
Type: 1
|
||||||
|
WasModified: 0
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 25
|
||||||
|
160 1270 560 1270 896 640 c 0
|
||||||
|
1232 10 1632 10 1632 10 c 1025
|
||||||
|
1632 70 m 5
|
||||||
|
1632 -50 l 1029
|
||||||
|
160 1210 m 5
|
||||||
|
160 1330 l 1029
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
EndUndoes
|
||||||
|
Redoes
|
||||||
|
EndRedoes
|
||||||
|
EndUndoRedoHistory
|
||||||
|
Back
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 25
|
||||||
|
160 1270 560 1270 896 640 c 0
|
||||||
|
1232 10 1632 10 1632 10 c 1025
|
||||||
|
1632 70 m 1
|
||||||
|
1632 -50 l 1025
|
||||||
|
160 1210 m 1
|
||||||
|
160 1330 l 1025
|
||||||
|
EndSplineSet
|
||||||
|
UndoRedoHistory
|
||||||
|
Layer: 1
|
||||||
|
Undoes
|
||||||
|
UndoOperation
|
||||||
|
Index: 0
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
1632 1210.01171875 m 1
|
||||||
|
1632 1329.98828125 l 1
|
||||||
|
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
|
||||||
|
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
|
||||||
|
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
|
||||||
|
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
|
||||||
|
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
|
||||||
|
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
|
||||||
|
160 -49.98828125 l 1
|
||||||
|
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
|
||||||
|
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
|
||||||
|
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
|
||||||
|
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
|
||||||
|
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
|
||||||
|
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
|
||||||
|
159.999999952 1210.01176537 m 1
|
||||||
|
159.999999952 1329.98823463 l 1
|
||||||
|
170.809951102 1329.98823463 504.536374276 1326.28810718 823.734604363 872.948478072 c 1
|
||||||
|
800.889124326 837.280193024 778.251310121 799.419416229 755.928040313 759.232259114 c 1
|
||||||
|
695.916689064 850.735795855 635.614260663 923.430234862 577.824293264 981.220202232 c 0
|
||||||
|
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 0
|
||||||
|
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 0
|
||||||
|
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 1
|
||||||
|
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 1
|
||||||
|
1632 1090.03515625 m 5
|
||||||
|
1632 1449.96484375 l 5
|
||||||
|
1558.47725996 1449.96484375 1167.58409474 1409.79522486 823.734604363 872.948478072 c 5
|
||||||
|
865.988935134 812.936984165 907.988680731 745.046220598 948.951069976 668.241740764 c 4
|
||||||
|
977.706682766 614.324966782 1006.85482384 565.317167145 1036.07195969 520.767740886 c 5
|
||||||
|
1042.35821703 532.084488601 1048.61953126 543.58571637 1054.85351562 555.274414062 c 4
|
||||||
|
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 4
|
||||||
|
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 5
|
||||||
|
1036.07195969 520.767740886 m 1
|
||||||
|
1096.08331094 429.264204145 1156.38573934 356.569765138 1214.17570674 298.779797768 c 0
|
||||||
|
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 0
|
||||||
|
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 0
|
||||||
|
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 1
|
||||||
|
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 1
|
||||||
|
1632.00000005 -49.9882346324 l 1
|
||||||
|
1621.1900489 -49.9882346324 1287.46362572 -46.2881071791 968.265395637 407.051521928 c 1
|
||||||
|
991.110875674 442.719806976 1013.74868988 480.580583771 1036.07195969 520.767740886 c 1
|
||||||
|
968.265395637 407.051521928 m 5
|
||||||
|
926.011064866 467.063015835 884.011319269 534.953779402 843.048930024 611.758259236 c 4
|
||||||
|
814.293317234 665.675033218 785.145176159 714.682832855 755.928040313 759.232259114 c 5
|
||||||
|
749.641782968 747.9155114 743.380468741 736.41428363 737.146484375 724.725585938 c 4
|
||||||
|
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 4
|
||||||
|
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 5
|
||||||
|
160 -169.96484375 l 5
|
||||||
|
233.522740042 -169.96484375 624.415905262 -129.795224857 968.265395637 407.051521928 c 5
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 1
|
||||||
|
Type: 1
|
||||||
|
WasModified: 0
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
1632 1090.03515625 m 5
|
||||||
|
1632 1449.96484375 l 5
|
||||||
|
1552.21679688 1449.96484375 1098.71386719 1402.66308594 737.146484375 724.725585938 c 4
|
||||||
|
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 4
|
||||||
|
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 5
|
||||||
|
160 -169.96484375 l 5
|
||||||
|
239.783203125 -169.96484375 693.286132812 -122.663085938 1054.85351562 555.274414062 c 4
|
||||||
|
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 4
|
||||||
|
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 5
|
||||||
|
1632 1210.01171875 m 1
|
||||||
|
1632 1329.98828125 l 1
|
||||||
|
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
|
||||||
|
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
|
||||||
|
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
|
||||||
|
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
|
||||||
|
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
|
||||||
|
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
|
||||||
|
160 -49.98828125 l 1
|
||||||
|
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
|
||||||
|
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
|
||||||
|
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
|
||||||
|
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
|
||||||
|
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
|
||||||
|
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
|
||||||
|
159.999999952 1210.01176537 m 5
|
||||||
|
159.999999952 1329.98823463 l 5
|
||||||
|
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 4
|
||||||
|
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 4
|
||||||
|
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 4
|
||||||
|
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 4
|
||||||
|
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 5
|
||||||
|
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 5
|
||||||
|
1632.00000005 -49.9882346324 l 5
|
||||||
|
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 4
|
||||||
|
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 4
|
||||||
|
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 4
|
||||||
|
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 4
|
||||||
|
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 5
|
||||||
|
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 5
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 2
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 29
|
||||||
|
160 1270 560 1270 896 640 c 4
|
||||||
|
1232 10 1632 10 1632 10 c 1029
|
||||||
|
1632 1210.01171875 m 1
|
||||||
|
1632 1329.98828125 l 1
|
||||||
|
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
|
||||||
|
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
|
||||||
|
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
|
||||||
|
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
|
||||||
|
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
|
||||||
|
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
|
||||||
|
160 -49.98828125 l 1
|
||||||
|
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
|
||||||
|
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
|
||||||
|
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
|
||||||
|
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
|
||||||
|
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
|
||||||
|
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
|
||||||
|
1632 1090.03515625 m 1
|
||||||
|
1632 1449.96484375 l 1
|
||||||
|
1552.21679688 1449.96484375 1098.71386719 1402.66308594 737.146484375 724.725585938 c 0
|
||||||
|
698.938476562 653.084960938 526.864257812 331.080078125 257.309570312 218.258789062 c 0
|
||||||
|
255.126953125 217.345703125 200.76171875 194.705078125 160 189.96484375 c 1
|
||||||
|
160 -169.96484375 l 1
|
||||||
|
239.783203125 -169.96484375 693.286132812 -122.663085938 1054.85351562 555.274414062 c 0
|
||||||
|
1093.06152344 626.915039062 1265.13574219 948.919921875 1534.69042969 1061.74121094 c 0
|
||||||
|
1536.87304688 1062.65429688 1591.23828125 1085.29492188 1632 1090.03515625 c 1
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 3
|
||||||
|
Type: 3
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 4
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
159.999999952 1210.01176537 m 5
|
||||||
|
159.999999952 1329.98823463 l 5
|
||||||
|
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 4
|
||||||
|
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 4
|
||||||
|
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 4
|
||||||
|
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 4
|
||||||
|
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 5
|
||||||
|
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 5
|
||||||
|
1632.00000005 -49.9882346324 l 5
|
||||||
|
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 4
|
||||||
|
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 4
|
||||||
|
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 4
|
||||||
|
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 4
|
||||||
|
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 5
|
||||||
|
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 5
|
||||||
|
159.999999857 1090.0352961 m 5
|
||||||
|
159.999999857 1449.9647039 l 5
|
||||||
|
239.782893731 1449.96470383 693.286263441 1402.66324695 1054.85320993 724.725222292 c 4
|
||||||
|
1093.06152816 653.084625607 1265.13598183 331.080480771 1534.69080463 218.25857115 c 4
|
||||||
|
1536.87267214 217.345352617 1591.23876559 194.705394151 1632.00000014 189.964703897 c 5
|
||||||
|
1632.00000014 -169.964703897 l 5
|
||||||
|
1552.21710627 -169.964703835 1098.71373656 -122.663246954 737.146790073 555.274777708 c 4
|
||||||
|
698.938471842 626.915374393 526.864018169 948.919519229 257.309195374 1061.74142885 c 4
|
||||||
|
255.127327856 1062.65464738 200.761234414 1085.29460585 159.999999857 1090.0352961 c 5
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 5
|
||||||
|
Type: 3
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 6
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 29
|
||||||
|
160 1270 560 1270 896 640 c 4
|
||||||
|
1232 10 1632 10 1632 10 c 1029
|
||||||
|
159.999999952 1210.01176537 m 1
|
||||||
|
159.999999952 1329.98823463 l 1
|
||||||
|
172.240934135 1329.98823462 598.550052583 1325.24364837 948.951069976 668.241740764 c 0
|
||||||
|
1036.77007573 503.581104976 1128.25010681 384.70539769 1214.17570674 298.779797768 c 0
|
||||||
|
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 0
|
||||||
|
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 0
|
||||||
|
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 1
|
||||||
|
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 1
|
||||||
|
1632.00000005 -49.9882346324 l 1
|
||||||
|
1619.75906587 -49.9882346228 1193.44994742 -45.2436483754 843.048930024 611.758259236 c 0
|
||||||
|
755.229924271 776.418895024 663.749893187 895.29460231 577.824293264 981.220202232 c 0
|
||||||
|
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 0
|
||||||
|
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 0
|
||||||
|
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 1
|
||||||
|
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 1
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 7
|
||||||
|
Type: 3
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 8
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 29
|
||||||
|
160 1270 560 1270 896 640 c 4
|
||||||
|
1232 10 1632 10 1632 10 c 1029
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 9
|
||||||
|
Type: 3
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 10
|
||||||
|
Type: 2
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 2
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
SplineSet
|
||||||
|
160 1270 m 29
|
||||||
|
160 1270 560 1270 896 640 c 4
|
||||||
|
1232 10 1632 10 1632 10 c 1029
|
||||||
|
EndSplineSet
|
||||||
|
EndUndoOperation
|
||||||
|
UndoOperation
|
||||||
|
Index: 11
|
||||||
|
Type: 1
|
||||||
|
WasModified: 1
|
||||||
|
WasOrder2: 0
|
||||||
|
Layer: 1
|
||||||
|
Width: 1792
|
||||||
|
VWidth: 1792
|
||||||
|
LBearingChange: 0
|
||||||
|
UnicodeEnc: 0
|
||||||
|
InstructionsLength: 0
|
||||||
|
EndUndoOperation
|
||||||
|
EndUndoes
|
||||||
|
Redoes
|
||||||
|
EndRedoes
|
||||||
|
EndUndoRedoHistory
|
||||||
|
Fore
|
||||||
|
SplineSet
|
||||||
|
1632 1210.01171875 m 1
|
||||||
|
1632 1329.98828125 l 1
|
||||||
|
1619.75878906 1329.98828125 1193.45019531 1325.24316406 843.048828125 668.2421875 c 0
|
||||||
|
755.229492188 503.581054688 663.75 384.705078125 577.82421875 298.780273438 c 0
|
||||||
|
473.91796875 194.873046875 377.610351562 138.502929688 303.73046875 107.581054688 c 0
|
||||||
|
262.674804688 90.396484375 228.48828125 81.078125 203.702148438 76.0087890625 c 0
|
||||||
|
176.166992188 70.3779296875 160.23046875 70 159.536132812 69.986328125 c 1
|
||||||
|
159.698242188 69.9873046875 160 69.98828125 160 69.98828125 c 1
|
||||||
|
160 -49.98828125 l 1
|
||||||
|
172.241210938 -49.98828125 598.549804688 -45.2431640625 948.951171875 611.7578125 c 0
|
||||||
|
1036.77050781 776.418945312 1128.25 895.294921875 1214.17578125 981.219726562 c 0
|
||||||
|
1318.08203125 1085.12695312 1414.38964844 1141.49707031 1488.26953125 1172.41894531 c 0
|
||||||
|
1529.32519531 1189.60351562 1563.51171875 1198.921875 1588.29785156 1203.99121094 c 0
|
||||||
|
1615.83300781 1209.62207031 1631.76953125 1210 1632.46386719 1210.01367188 c 1
|
||||||
|
1632.30175781 1210.01269531 1632 1210.01171875 1632 1210.01171875 c 1
|
||||||
|
159.999999952 1210.01176537 m 1
|
||||||
|
159.999999952 1329.98823463 l 1
|
||||||
|
170.809951102 1329.98823463 504.536374276 1326.28810718 823.734604363 872.948478072 c 1
|
||||||
|
800.889124326 837.280193024 778.251310121 799.419416229 755.928040313 759.232259114 c 1
|
||||||
|
695.916689064 850.735795855 635.614260663 923.430234862 577.824293264 981.220202232 c 0
|
||||||
|
473.917602143 1085.12689335 377.61065751 1141.49706263 303.730893464 1172.41936621 c 0
|
||||||
|
262.674555191 1189.60345677 228.488523437 1198.92230209 203.702403502 1203.99126863 c 0
|
||||||
|
176.167181121 1209.62244935 160.230079948 1210.00005891 159.536222574 1210.01396385 c 1
|
||||||
|
159.698263781 1210.01275358 159.999999952 1210.01176537 159.999999952 1210.01176537 c 1
|
||||||
|
1036.07195969 520.767740886 m 1
|
||||||
|
1096.08331094 429.264204145 1156.38573934 356.569765138 1214.17570674 298.779797768 c 0
|
||||||
|
1318.08239786 194.873106647 1414.38934249 138.502937368 1488.26910654 107.580633787 c 0
|
||||||
|
1529.32544481 90.3965432265 1563.51147656 81.0776979108 1588.2975965 76.0087313726 c 0
|
||||||
|
1615.83281888 70.3775506458 1631.76992005 69.9999410877 1632.46377743 69.986036148 c 1
|
||||||
|
1632.30173622 69.9872464204 1632.00000005 69.9882346324 1632.00000005 69.9882346324 c 1
|
||||||
|
1632.00000005 -49.9882346324 l 1
|
||||||
|
1621.1900489 -49.9882346324 1287.46362572 -46.2881071791 968.265395637 407.051521928 c 1
|
||||||
|
991.110875674 442.719806976 1013.74868988 480.580583771 1036.07195969 520.767740886 c 1
|
||||||
|
EndSplineSet
|
||||||
|
EndChar
|
||||||
EndChars
|
EndChars
|
||||||
EndSplineFont
|
EndSplineFont
|
||||||
|
|
BIN
res/icons.ttf
|
@ -168,3 +168,7 @@ void DivEngine::setConf(String key, String value) {
|
||||||
bool DivEngine::hasConf(String key) {
|
bool DivEngine::hasConf(String key) {
|
||||||
return conf.has(key);
|
return conf.has(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivConfig& DivEngine::getConfObject() {
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_ENV_RELEASE,
|
DIV_CMD_ENV_RELEASE,
|
||||||
DIV_CMD_INSTRUMENT, // (ins, force)
|
DIV_CMD_INSTRUMENT, // (ins, force)
|
||||||
DIV_CMD_VOLUME, // (vol)
|
DIV_CMD_VOLUME, // (vol)
|
||||||
|
// TODO: think of possibly moving this
|
||||||
DIV_CMD_GET_VOLUME, // () -> vol
|
DIV_CMD_GET_VOLUME, // () -> vol
|
||||||
|
// TODO: move. shouldn't be a command.
|
||||||
DIV_CMD_GET_VOLMAX, // () -> volMax
|
DIV_CMD_GET_VOLMAX, // () -> volMax
|
||||||
DIV_CMD_NOTE_PORTA, // (target, speed) -> 2 if target reached
|
DIV_CMD_NOTE_PORTA, // (target, speed) -> 2 if target reached
|
||||||
DIV_CMD_PITCH, // (pitch)
|
DIV_CMD_PITCH, // (pitch)
|
||||||
|
@ -589,6 +591,14 @@ class DivDispatch {
|
||||||
*/
|
*/
|
||||||
virtual bool isVolGlobal();
|
virtual bool isVolGlobal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* map MIDI velocity (from 0 to 127) to chip volume.
|
||||||
|
* @param ch the chip channel. -1 means N/A.
|
||||||
|
* @param vel input velocity, from 0.0 to 1.0.
|
||||||
|
* @return output volume.
|
||||||
|
*/
|
||||||
|
virtual int mapVelocity(int ch, float vel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the lowest note in a portamento.
|
* get the lowest note in a portamento.
|
||||||
* @param ch the channel in question.
|
* @param ch the channel in question.
|
||||||
|
@ -782,7 +792,7 @@ class DivDispatch {
|
||||||
#define NOTE_FNUM_BLOCK(x,bits) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits)
|
#define NOTE_FNUM_BLOCK(x,bits) parent->calcBaseFreqFNumBlock(chipClock,CHIP_FREQBASE,x,bits)
|
||||||
|
|
||||||
// this is for volume scaling calculation.
|
// this is for volume scaling calculation.
|
||||||
#define VOL_SCALE_LINEAR(x,y,range) (((x)*(y))/(range))
|
#define VOL_SCALE_LINEAR(x,y,range) ((parent->song.ceilVolumeScaling)?((((x)*(y))+(range-1))/(range)):(((x)*(y))/(range)))
|
||||||
#define VOL_SCALE_LOG(x,y,range) (CLAMP(((x)+(y))-(range),0,(range)))
|
#define VOL_SCALE_LOG(x,y,range) (CLAMP(((x)+(y))-(range),0,(range)))
|
||||||
#define VOL_SCALE_LINEAR_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LINEAR(x,y,range)):(VOL_SCALE_LOG(x,y,range)))
|
#define VOL_SCALE_LINEAR_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LINEAR(x,y,range)):(VOL_SCALE_LOG(x,y,range)))
|
||||||
#define VOL_SCALE_LOG_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LOG(x,y,range)):(VOL_SCALE_LINEAR(x,y,range)))
|
#define VOL_SCALE_LOG_BROKEN(x,y,range) ((parent->song.newVolumeScaling)?(VOL_SCALE_LOG(x,y,range)):(VOL_SCALE_LINEAR(x,y,range)))
|
||||||
|
|
|
@ -1519,6 +1519,11 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
while (playing && curOrder<goal) {
|
while (playing && curOrder<goal) {
|
||||||
if (nextTick(preserveDrift)) {
|
if (nextTick(preserveDrift)) {
|
||||||
skipping=false;
|
skipping=false;
|
||||||
|
cmdStream.clear();
|
||||||
|
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(false);
|
||||||
|
if (goal>0 || goalRow>0) {
|
||||||
|
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->forceIns();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!preserveDrift) {
|
if (!preserveDrift) {
|
||||||
|
@ -1530,6 +1535,11 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
while (playing && (curRow<goalRow || ticks>1)) {
|
while (playing && (curRow<goalRow || ticks>1)) {
|
||||||
if (nextTick(preserveDrift)) {
|
if (nextTick(preserveDrift)) {
|
||||||
skipping=false;
|
skipping=false;
|
||||||
|
cmdStream.clear();
|
||||||
|
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(false);
|
||||||
|
if (goal>0 || goalRow>0) {
|
||||||
|
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->forceIns();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!preserveDrift) {
|
if (!preserveDrift) {
|
||||||
|
@ -2175,6 +2185,13 @@ int DivEngine::getMaxVolumeChan(int ch) {
|
||||||
return chan[ch].volMax>>8;
|
return chan[ch].volMax>>8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivEngine::mapVelocity(int ch, float vel) {
|
||||||
|
if (ch<0) return 0;
|
||||||
|
if (ch>=chans) return 0;
|
||||||
|
if (disCont[dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||||
|
return disCont[dispatchOfChan[ch]].dispatch->mapVelocity(dispatchChanOfChan[ch],vel);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char DivEngine::getOrder() {
|
unsigned char DivEngine::getOrder() {
|
||||||
return prevOrder;
|
return prevOrder;
|
||||||
}
|
}
|
||||||
|
@ -3375,6 +3392,14 @@ void DivEngine::setMidiDirect(bool value) {
|
||||||
midiIsDirect=value;
|
midiIsDirect=value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivEngine::setMidiDirectProgram(bool value) {
|
||||||
|
midiIsDirectProgram=value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivEngine::setMidiVolExp(float value) {
|
||||||
|
midiVolExp=value;
|
||||||
|
}
|
||||||
|
|
||||||
void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
|
void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
|
||||||
midiCallback=what;
|
midiCallback=what;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ class DivWorkPool;
|
||||||
|
|
||||||
#define DIV_UNSTABLE
|
#define DIV_UNSTABLE
|
||||||
|
|
||||||
#define DIV_VERSION "dev187"
|
#define DIV_VERSION "dev190"
|
||||||
#define DIV_ENGINE_VERSION 187
|
#define DIV_ENGINE_VERSION 190
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
@ -176,25 +176,25 @@ struct DivNoteEvent {
|
||||||
signed char channel;
|
signed char channel;
|
||||||
unsigned char ins;
|
unsigned char ins;
|
||||||
signed char note, volume;
|
signed char note, volume;
|
||||||
bool on, nop, pad1, pad2;
|
bool on, nop, insChange, fromMIDI;
|
||||||
DivNoteEvent(int c, int i, int n, int v, bool o):
|
DivNoteEvent(int c, int i, int n, int v, bool o, bool ic=false, bool fm=false):
|
||||||
channel(c),
|
channel(c),
|
||||||
ins(i),
|
ins(i),
|
||||||
note(n),
|
note(n),
|
||||||
volume(v),
|
volume(v),
|
||||||
on(o),
|
on(o),
|
||||||
nop(false),
|
nop(false),
|
||||||
pad1(false),
|
insChange(ic),
|
||||||
pad2(false) {}
|
fromMIDI(fm) {}
|
||||||
DivNoteEvent():
|
DivNoteEvent():
|
||||||
channel(-1),
|
channel(-1),
|
||||||
ins(0),
|
ins(0),
|
||||||
note(0),
|
note(0),
|
||||||
volume(0),
|
volume(-1),
|
||||||
on(false),
|
on(false),
|
||||||
nop(true),
|
nop(true),
|
||||||
pad1(false),
|
insChange(false),
|
||||||
pad2(false) {}
|
fromMIDI(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DivDispatchContainer {
|
struct DivDispatchContainer {
|
||||||
|
@ -415,6 +415,7 @@ class DivEngine {
|
||||||
bool firstTick;
|
bool firstTick;
|
||||||
bool skipping;
|
bool skipping;
|
||||||
bool midiIsDirect;
|
bool midiIsDirect;
|
||||||
|
bool midiIsDirectProgram;
|
||||||
bool lowLatency;
|
bool lowLatency;
|
||||||
bool systemsRegistered;
|
bool systemsRegistered;
|
||||||
bool hasLoadedSomething;
|
bool hasLoadedSomething;
|
||||||
|
@ -423,6 +424,7 @@ class DivEngine {
|
||||||
bool midiOutProgramChange;
|
bool midiOutProgramChange;
|
||||||
int midiOutMode;
|
int midiOutMode;
|
||||||
int midiOutTimeRate;
|
int midiOutTimeRate;
|
||||||
|
float midiVolExp;
|
||||||
int softLockCount;
|
int softLockCount;
|
||||||
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed, elapsedBars, elapsedBeats, curSpeed;
|
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed, elapsedBars, elapsedBeats, curSpeed;
|
||||||
size_t curSubSongIndex;
|
size_t curSubSongIndex;
|
||||||
|
@ -700,6 +702,9 @@ class DivEngine {
|
||||||
double getConfDouble(String key, double fallback);
|
double getConfDouble(String key, double fallback);
|
||||||
String getConfString(String key, String fallback);
|
String getConfString(String key, String fallback);
|
||||||
|
|
||||||
|
// get config object
|
||||||
|
DivConfig& getConfObject();
|
||||||
|
|
||||||
// set a config value
|
// set a config value
|
||||||
void setConf(String key, bool value);
|
void setConf(String key, bool value);
|
||||||
void setConf(String key, int value);
|
void setConf(String key, int value);
|
||||||
|
@ -850,6 +855,9 @@ class DivEngine {
|
||||||
// get channel max volume
|
// get channel max volume
|
||||||
int getMaxVolumeChan(int chan);
|
int getMaxVolumeChan(int chan);
|
||||||
|
|
||||||
|
// map MIDI velocity to volume
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
|
|
||||||
// get current order
|
// get current order
|
||||||
unsigned char getOrder();
|
unsigned char getOrder();
|
||||||
|
|
||||||
|
@ -1184,6 +1192,12 @@ class DivEngine {
|
||||||
// set MIDI direct channel map
|
// set MIDI direct channel map
|
||||||
void setMidiDirect(bool value);
|
void setMidiDirect(bool value);
|
||||||
|
|
||||||
|
// set MIDI direct program change
|
||||||
|
void setMidiDirectProgram(bool value);
|
||||||
|
|
||||||
|
// set MIDI volume curve exponent
|
||||||
|
void setMidiVolExp(float value);
|
||||||
|
|
||||||
// set MIDI input callback
|
// set MIDI input callback
|
||||||
// if the specified function returns -2, note feedback will be inhibited.
|
// if the specified function returns -2, note feedback will be inhibited.
|
||||||
void setMidiCallback(std::function<int(const TAMidiMessage&)> what);
|
void setMidiCallback(std::function<int(const TAMidiMessage&)> what);
|
||||||
|
@ -1253,6 +1267,7 @@ class DivEngine {
|
||||||
firstTick(false),
|
firstTick(false),
|
||||||
skipping(false),
|
skipping(false),
|
||||||
midiIsDirect(false),
|
midiIsDirect(false),
|
||||||
|
midiIsDirectProgram(false),
|
||||||
lowLatency(false),
|
lowLatency(false),
|
||||||
systemsRegistered(false),
|
systemsRegistered(false),
|
||||||
hasLoadedSomething(false),
|
hasLoadedSomething(false),
|
||||||
|
@ -1261,6 +1276,7 @@ class DivEngine {
|
||||||
midiOutProgramChange(false),
|
midiOutProgramChange(false),
|
||||||
midiOutMode(DIV_MIDI_MODE_NOTE),
|
midiOutMode(DIV_MIDI_MODE_NOTE),
|
||||||
midiOutTimeRate(0),
|
midiOutTimeRate(0),
|
||||||
|
midiVolExp(2.0f), // General MIDI standard
|
||||||
softLockCount(0),
|
softLockCount(0),
|
||||||
subticks(0),
|
subticks(0),
|
||||||
ticks(0),
|
ticks(0),
|
||||||
|
|
|
@ -1873,6 +1873,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
if (ds.version<184) {
|
if (ds.version<184) {
|
||||||
ds.resetArpPhaseOnNewNote=false;
|
ds.resetArpPhaseOnNewNote=false;
|
||||||
}
|
}
|
||||||
|
if (ds.version<188) {
|
||||||
|
ds.ceilVolumeScaling=false;
|
||||||
|
}
|
||||||
ds.isDMF=false;
|
ds.isDMF=false;
|
||||||
|
|
||||||
reader.readS(); // reserved
|
reader.readS(); // reserved
|
||||||
|
@ -2182,7 +2185,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
if (ds.version>=39) {
|
if (ds.version>=39) {
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
|
if (ds.version<189) {
|
||||||
subSong->chanShow[i]=reader.readC();
|
subSong->chanShow[i]=reader.readC();
|
||||||
|
subSong->chanShowChanOsc[i]=subSong->chanShow[i];
|
||||||
|
} else {
|
||||||
|
unsigned char tempchar=reader.readC();
|
||||||
|
subSong->chanShow[i]=tempchar&1;
|
||||||
|
subSong->chanShowChanOsc[i]=(tempchar&2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
|
@ -2409,7 +2419,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<3; i++) {
|
if (ds.version>=188) {
|
||||||
|
ds.ceilVolumeScaling=reader.readC();
|
||||||
|
} else {
|
||||||
|
reader.readC();
|
||||||
|
}
|
||||||
|
for (int i=0; i<2; i++) {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2580,7 +2595,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
|
if (ds.version<189) {
|
||||||
subSong->chanShow[i]=reader.readC();
|
subSong->chanShow[i]=reader.readC();
|
||||||
|
subSong->chanShowChanOsc[i]=subSong->chanShow[i];
|
||||||
|
} else {
|
||||||
|
unsigned char tempchar=reader.readC();
|
||||||
|
subSong->chanShow[i]=tempchar&1;
|
||||||
|
subSong->chanShowChanOsc[i]=tempchar&2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<tchans; i++) {
|
for (int i=0; i<tchans; i++) {
|
||||||
|
@ -3449,12 +3471,14 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
for(int i=0; i<chCount; i++) {
|
for(int i=0; i<chCount; i++) {
|
||||||
ds.subsong[0]->chanShow[i]=true;
|
ds.subsong[0]->chanShow[i]=true;
|
||||||
|
ds.subsong[0]->chanShowChanOsc[i]=true;
|
||||||
ds.subsong[0]->chanName[i]=fmt::sprintf("Channel %d",i+1);
|
ds.subsong[0]->chanName[i]=fmt::sprintf("Channel %d",i+1);
|
||||||
ds.subsong[0]->chanShortName[i]=fmt::sprintf("C%d",i+1);
|
ds.subsong[0]->chanShortName[i]=fmt::sprintf("C%d",i+1);
|
||||||
}
|
}
|
||||||
for(int i=chCount; i<ds.systemLen*4; i++) {
|
for(int i=chCount; i<ds.systemLen*4; i++) {
|
||||||
ds.subsong[0]->pat[i].effectCols=1;
|
ds.subsong[0]->pat[i].effectCols=1;
|
||||||
ds.subsong[0]->chanShow[i]=false;
|
ds.subsong[0]->chanShow[i]=false;
|
||||||
|
ds.subsong[0]->chanShowChanOsc[i]=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// instrument creation
|
// instrument creation
|
||||||
|
@ -5402,7 +5426,10 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
w->writeC(subSong->chanShow[i]);
|
w->writeC(
|
||||||
|
(subSong->chanShow[i]?1:0)|
|
||||||
|
(subSong->chanShowChanOsc[i]?2:0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
|
@ -5494,7 +5521,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
||||||
w->writeC(song.preNoteNoEffect);
|
w->writeC(song.preNoteNoEffect);
|
||||||
w->writeC(song.oldDPCM);
|
w->writeC(song.oldDPCM);
|
||||||
w->writeC(song.resetArpPhaseOnNewNote);
|
w->writeC(song.resetArpPhaseOnNewNote);
|
||||||
for (int i=0; i<3; i++) {
|
w->writeC(song.ceilVolumeScaling);
|
||||||
|
for (int i=0; i<2; i++) {
|
||||||
w->writeC(0);
|
w->writeC(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5559,7 +5587,10 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
w->writeC(subSong->chanShow[i]);
|
w->writeC(
|
||||||
|
(subSong->chanShow[i]?1:0)|
|
||||||
|
(subSong->chanShowChanOsc[i]?2:0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
|
|
|
@ -102,6 +102,11 @@ bool DivDispatch::isVolGlobal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivDispatch::mapVelocity(int ch, float vel) {
|
||||||
|
const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0))));
|
||||||
|
return round(vel*volMax);
|
||||||
|
}
|
||||||
|
|
||||||
int DivDispatch::getPortaFloor(int ch) {
|
int DivDispatch::getPortaFloor(int ch) {
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
|
@ -719,6 +719,10 @@ DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformAY8910::mapVelocity(int ch, float vel) {
|
||||||
|
return round(15.0*pow(vel,0.33));
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformAY8910::getRegisterPool() {
|
unsigned char* DivPlatformAY8910::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ class DivPlatformAY8910: public DivDispatch {
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void flushWrites();
|
void flushWrites();
|
||||||
|
|
|
@ -718,6 +718,10 @@ DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformAY8930::mapVelocity(int ch, float vel) {
|
||||||
|
return round(31.0*pow(vel,0.22));
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformAY8930::getRegisterPool() {
|
unsigned char* DivPlatformAY8930::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,7 @@ class DivPlatformAY8930: public DivDispatch {
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -186,6 +186,17 @@ class DivPlatformOPN: public DivPlatformFMBase {
|
||||||
void setCombo(bool combo) {
|
void setCombo(bool combo) {
|
||||||
useCombo=combo;
|
useCombo=combo;
|
||||||
}
|
}
|
||||||
|
virtual int mapVelocity(int ch, float vel) {
|
||||||
|
if (ch==csmChan) return vel*127.0;
|
||||||
|
if (ch==adpcmBChanOffs) return vel*255.0;
|
||||||
|
if (ch>=adpcmAChanOffs) {
|
||||||
|
if (vel==0) return 0;
|
||||||
|
if (vel>=1.0) return 31;
|
||||||
|
return CLAMP(round(32.0-(56.0-log2(vel*127.0)*8.0)),0,31);
|
||||||
|
}
|
||||||
|
if (ch>=psgChanOffs) return round(15.0*pow(vel,0.33));
|
||||||
|
return DivPlatformFMBase::mapVelocity(ch,vel);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -122,6 +122,20 @@ class DivPlatformFMBase: public DivDispatch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int mapVelocity(int ch, float vel) {
|
||||||
|
// -0.75dB per step
|
||||||
|
// -6: 64: 8
|
||||||
|
// -12: 32: 16
|
||||||
|
// -18: 16: 24
|
||||||
|
// -24: 8: 32
|
||||||
|
// -30: 4: 40
|
||||||
|
// -36: 2: 48
|
||||||
|
// -42: 1: 56
|
||||||
|
if (vel==0) return 0;
|
||||||
|
if (vel>=1.0) return 127;
|
||||||
|
return CLAMP(round(128.0-(56.0-log2(vel*127.0)*8.0)),0,127);
|
||||||
|
}
|
||||||
|
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
DivPlatformFMBase():
|
DivPlatformFMBase():
|
||||||
|
|
|
@ -1300,6 +1300,12 @@ DivDispatchOscBuffer* DivPlatformGenesis::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformGenesis::mapVelocity(int ch, float vel) {
|
||||||
|
if (ch==csmChan) return DivPlatformOPN::mapVelocity(ch,vel);
|
||||||
|
if (ch>5) return DivPlatformOPN::mapVelocity(5,vel);
|
||||||
|
return DivPlatformOPN::mapVelocity(ch,vel);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformGenesis::getRegisterPool() {
|
unsigned char* DivPlatformGenesis::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
||||||
virtual unsigned short getPan(int chan);
|
virtual unsigned short getPan(int chan);
|
||||||
DivSamplePos getSamplePos(int ch);
|
DivSamplePos getSamplePos(int ch);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
virtual int mapVelocity(int ch, float vel);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -818,6 +818,12 @@ DivDispatchOscBuffer* DivPlatformGenesisExt::getOscBuffer(int ch) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformGenesisExt::mapVelocity(int ch, float vel) {
|
||||||
|
if (ch>=extChanOffs+4) return DivPlatformGenesis::mapVelocity(ch-3,vel);
|
||||||
|
if (ch>=extChanOffs) return DivPlatformGenesis::mapVelocity(extChanOffs,vel);
|
||||||
|
return DivPlatformGenesis::mapVelocity(ch,vel);
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformGenesisExt::reset() {
|
void DivPlatformGenesisExt::reset() {
|
||||||
DivPlatformGenesis::reset();
|
DivPlatformGenesis::reset();
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
unsigned short getPan(int chan);
|
unsigned short getPan(int chan);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
void reset();
|
void reset();
|
||||||
void forceIns();
|
void forceIns();
|
||||||
void tick(bool sysTick=true);
|
void tick(bool sysTick=true);
|
||||||
|
|
|
@ -2104,6 +2104,21 @@ DivDispatchOscBuffer* DivPlatformOPL::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformOPL::mapVelocity(int ch, float vel) {
|
||||||
|
if (ch==adpcmChan) return vel*255.0;
|
||||||
|
// -0.75dB per step
|
||||||
|
// -6: 64: 8
|
||||||
|
// -12: 32: 16
|
||||||
|
// -18: 16: 24
|
||||||
|
// -24: 8: 32
|
||||||
|
// -30: 4: 40
|
||||||
|
// -36: 2: 48
|
||||||
|
// -42: 1: 56
|
||||||
|
if (vel==0) return 0;
|
||||||
|
if (vel>=1.0) return 63;
|
||||||
|
return CLAMP(round(64.0-(56.0-log2(vel*127.0)*8.0)),0,63);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformOPL::getRegisterPool() {
|
unsigned char* DivPlatformOPL::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
unsigned short getPan(int chan);
|
unsigned short getPan(int chan);
|
||||||
DivChannelPair getPaired(int chan);
|
DivChannelPair getPaired(int chan);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -962,6 +962,13 @@ DivDispatchOscBuffer* DivPlatformOPLL::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformOPLL::mapVelocity(int ch, float vel) {
|
||||||
|
// -3dB per step
|
||||||
|
if (vel==0) return 0;
|
||||||
|
if (vel>=1.0) return 15;
|
||||||
|
return CLAMP(round(16.0-(14.0-log2(vel*127.0)*2.0)),0,15);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformOPLL::getRegisterPool() {
|
unsigned char* DivPlatformOPLL::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ class DivPlatformOPLL: public DivDispatch {
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
|
int mapVelocity(int ch, float vel);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -539,6 +539,10 @@ DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) {
|
||||||
return oscBuf[ch];
|
return oscBuf[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DivPlatformPCE::mapVelocity(int ch, float vel) {
|
||||||
|
return round(31.0*pow(vel,0.22));
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformPCE::getRegisterPool() {
|
unsigned char* DivPlatformPCE::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
|