Skip to content

Commit

Permalink
Send and save FKS data only if it's present, otherwise send only head…
Browse files Browse the repository at this point in the history
…er + AMEM + VMEM, thus preventing warnings on DX7II v1.6+ about cartridge not being writable
  • Loading branch information
bladeSk committed Nov 12, 2024
1 parent b3499fd commit eb0c28c
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 32 deletions.
4 changes: 4 additions & 0 deletions src/components/carts/CartItem/CartItem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
}
}

.CartItem__dx7ii_fks {
color: $accentColor4;
}

// drag & drop stuff
.CartItem__dragAreaBefore {
position: absolute;
Expand Down
8 changes: 6 additions & 2 deletions src/components/carts/CartItem/CartItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import './CartItem.scss'
export interface Props<T = any> {
className?: string
name: string
isDX7II?: boolean
isEmpty?: boolean
index: number
number: number
dataType: string
data: T
subType?: 'DX7II' | 'DX7II-FKS'
dragNDropCtx: DragNDropData
selected?: boolean
onDrop: (dropData: T, index: number, where: 'before' | 'on') => void
Expand Down Expand Up @@ -85,7 +85,11 @@ export default class CartItem<T = any> extends React.PureComponent<Props<T>, Sta

<div className="CartItem__name">{this.props.name}</div>

{this.props.isDX7II && <span className="CartItem__dx7ii" title="Uses DX7II features"><IISvg /></span>}
{this.props.subType == 'DX7II' && <span className="CartItem__dx7ii" title="Uses DX7II features"><IISvg /></span>}
{this.props.subType == 'DX7II-FKS' && <span
className="CartItem__dx7ii CartItem__dx7ii_fks"
title="Uses DX7II features + FKS"
><IISvg /></span>}

{dragNDropCtx.type == dataType && dragNDropCtx.data != data && <>
<div className={clsx('CartItem__dragAreaBefore', draggingOverBefore && 'CartItem__dragAreaBefore_active')}
Expand Down
4 changes: 4 additions & 0 deletions src/components/carts/CartViewer/CartViewer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@
font-size: 20px;
}
}

.CartViewerHelp__secondary {
color: $textColorD2;
}
5 changes: 4 additions & 1 deletion src/components/carts/CartViewer/CartViewerDX7Voice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ export default class CartViewerDX7Voice extends CartViewerBase<DX7VoiceCart> {
index={i}
number={cart.bank * 32 + i + 1}
name={voice.name}
isDX7II={voice.version == 2}
subType={voice.version == 2
? (voice.dx7iiFeatures.fks ? 'DX7II-FKS' : 'DX7II')
: undefined
}
isEmpty={voice.name == 'INIT VOICE'}
dataType="DX7Voice"
data={voice}
Expand Down
1 change: 1 addition & 0 deletions src/components/carts/CartViewer/CartViewerHelp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default class CartViewerHelp extends CartViewerBase<null, State> {
<li>press EDIT</li>
<li>press button #14 (UTILITY-TUNE) until you see "Memory protect"</li>
<li>set INT (internal) to OFF</li>
<li className="CartViewerHelp__secondary">optional, FKS voices only - you'll need a RAM cartridge and set CRT protection to OFF</li>
</ul>

<p><b className="accent1">DX7</b></p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class InlineDX7VoiceEditor extends React.PureComponent<Props, Sta
}

render(): React.ReactElement {
let dx7iiFeatures = this.props.voice.dx7iiFeatures
let dx7iiFeatures = this.props.voice.dx7iiFeaturesString

return <form
className={clsx('InlineEditor', 'InlineDX7VoiceEditor', this.props.className)}
Expand Down
73 changes: 52 additions & 21 deletions src/core/models/DX7Voice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export class DX7Voice {
if (this.fksData.length != DEFAULT_FKS.length) throw new Error('Incorrect FKS length')

if (!amemData) this.copyAmsFromVmemToAmem()

// clear FKS byte for default FKS data - DX7II v1.6 and newer may dump the voices without FKS data
if (uint8ArraysEqual(this.fksData, DEFAULT_FKS)) {
this.amemData[0] = 0
}
}

clone(): DX7Voice {
Expand Down Expand Up @@ -62,12 +67,12 @@ export class DX7Voice {
(am[2] & 0b111000) >> 3,
am[3] & 0b111,
(am[3] & 0b111000) >> 3,
) > 3) return 2
) > 3) return 2 // uses AM sensitivity > 3 on any operator

return 1
}

get dx7iiFeatures(): string[] {
get dx7iiFeatures() {
let am = this.amemData
let fks = am[0]
let ams1 = am[1] & 0b111
Expand Down Expand Up @@ -95,26 +100,52 @@ export class DX7Voice {
let unisonDetune = am[34] & 0b0000111
let fccs1 = (am[34] & 0b0001000) >> 3

return {
fks: !!fks,
ams: !!ams,
rndp: !!rndp,
vpsw: !!vpsw,
ltrg: !!ltrg,
pegr: !!pegr,
pitchEgScl: !!pitchEgScl,
mono: !!mono,
unison: !!unison,
unisonDetune: !!unisonDetune,
portamento: !!portamento,
pitchBend: !!pitchBend,
modWheel: !!modWheel,
fc1: !!fc1,
fc2: !!fc2,
bc: !!bc,
at: !!at,
mc: !!mc,
fccs1: !!fccs1,
}
}

get dx7iiFeaturesString(): string[] {
let f = this.dx7iiFeatures

return [
fks && 'Fractional key scaling',
ams && 'AM sens. 4-7',
rndp && 'Random pitch',
vpsw && 'Pitch EG vel. sens.',
ltrg && 'Multi LFO',
pegr && 'Pitch EG range',
pitchEgScl && 'Pitch EG scl. rate',
mono && 'Monophonic',
unison && 'Unison poly',
unisonDetune && 'Unison detune',
portamento && 'Portamento',
pitchBend && 'Pitch B. params',
modWheel && 'Mod W. params',
fc1 && 'FC1 params',
fc2 && 'FC2 params',
bc && 'BC params',
at && 'AT params',
mc && 'MIDI in 1 params',
fccs1 && 'FC1 as CS1',
f.fks && 'Fractional key scaling',
f.ams && 'AM sens. 4-7',
f.rndp && 'Random pitch',
f.vpsw && 'Pitch EG vel. sens.',
f.ltrg && 'Multi LFO',
f.pegr && 'Pitch EG range',
f.pitchEgScl && 'Pitch EG scl. rate',
f.mono && 'Monophonic',
f.unison && 'Unison poly',
f.unisonDetune && 'Unison detune',
f.portamento && 'Portamento',
f.pitchBend && 'Pitch B. params',
f.modWheel && 'Mod W. params',
f.fc1 && 'FC1 params',
f.fc2 && 'FC2 params',
f.bc && 'BC params',
f.at && 'AT params',
f.mc && 'MIDI in 1 params',
f.fccs1 && 'FC1 as CS1',
].filter(Boolean) as string[]
}

Expand Down
17 changes: 10 additions & 7 deletions src/core/models/DX7VoiceCart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,15 @@ export class DX7VoiceCart {

dataArr.push(this.bank == 1 ? DX7II_HEADER_2 : DX7II_HEADER_1)

let fksData: Uint8Array = mergeUint8Arrays([
FKS_HEADER,
...(this.voices.map(patch => patch.fksData)),
new Uint8Array([ 0xF7 ]),
])

dataArr.push(fksData)
if (this.voices.some(voice => voice.dx7iiFeatures.fks)) {
let fksData: Uint8Array = mergeUint8Arrays([
FKS_HEADER,
...(this.voices.map(patch => patch.fksData)),
new Uint8Array([ 0xF7 ]),
])

dataArr.push(fksData)
}

let amemData = mergeUint8Arrays([
AMEM_HEADER,
Expand All @@ -157,6 +159,7 @@ export class DX7VoiceCart {
return true
}

/** Full voice data dump: FKS, AMEM and VMEM. */
private static isDX7IICart(data: Uint8Array): boolean {
if (data.length != 21404) return false
if (!dataMatchesN6(DX7II_HEADER_1, data, 0) && !dataMatchesN6(DX7II_HEADER_2, data, 0)) return false
Expand Down

0 comments on commit eb0c28c

Please sign in to comment.