Explicit unpack of dx7 patches

Parameter changes and the like should work with unpacked patches,
so now we have an explicit patch unpack. In the future, the unpacking
will move out of the Dx7Note constructor.
bklimt
Raph Levien 12 years ago
parent ee72c697c1
commit 904ff23afc
  1. 4
      cpp/src/SynthApp/SynthMain.mm
  2. 24
      cpp/src/SynthApp/midi_in_mac.cc
  3. 10
      cpp/src/core.xcodeproj/project.pbxproj
  4. 27
      cpp/src/dx7note.cc
  5. 51
      cpp/src/patch.cc
  6. 22
      cpp/src/patch.h

@ -170,7 +170,9 @@ int SynthMain::SynthInit() {
cout << err << endl; cout << err << endl;
return 1; return 1;
} }
midi_in_mac_.Init(CFSTR("KeyRig 49"), &ring_buffer_); CFStringRef usbname = CFSTR("MPK mini");
// CFStringRef usbname = CFST("KeyRig 49");
midi_in_mac_.Init(usbname, &ring_buffer_);
startplayback(); startplayback();
return 0; return 0;
} }

@ -17,9 +17,25 @@
#include <iostream> #include <iostream>
#include "midi_in_mac.h" #include "midi_in_mac.h"
#define DEBUG_MIDI_BYTES
using std::cout;
using std::endl;
void MidiInMac::OnRead(const MIDIPacketList *pktlist) { void MidiInMac::OnRead(const MIDIPacketList *pktlist) {
const MIDIPacket *packet = &(pktlist->packet[0]); const MIDIPacket *packet = &(pktlist->packet[0]);
for (int i = 0; i < pktlist->numPackets; ++i) { for (int i = 0; i < pktlist->numPackets; ++i) {
#if defined(DEBUG_MIDI_BYTES)
cout << "MIDI DATA:";
cout.fill('0');
for (size_t i = 0; i < packet->length; i++) {
cout << " ";
cout.width(2);
cout << std::hex << static_cast<int>(packet->data[i]);
cout.width();
}
cout << endl;
#endif
ring_buffer_->Write(packet->data, packet->length); ring_buffer_->Write(packet->data, packet->length);
packet = MIDIPacketNext(packet); packet = MIDIPacketNext(packet);
} }
@ -44,6 +60,14 @@ bool MidiInMac::Init(CFStringRef name, RingBuffer *ring_buffer) {
MIDIObjectGetProperties(device_ref, &midi_device_properties, true); MIDIObjectGetProperties(device_ref, &midi_device_properties, true);
CFStringRef dev_name = NULL; CFStringRef dev_name = NULL;
s = MIDIObjectGetStringProperty(device_ref, kMIDIPropertyName, &dev_name); s = MIDIObjectGetStringProperty(device_ref, kMIDIPropertyName, &dev_name);
#if defined(DEBUG_USB_NAMES)
char buf[64];
if (CFStringGetCString(dev_name, buf, sizeof(buf), kCFStringEncodingASCII)) {
std::cout << "midi name =" << buf << std::endl;
} else {
std::cout << "error converting" << std::endl;
}
#endif
CFComparisonResult comparison = CFStringCompare(dev_name, name, 0); CFComparisonResult comparison = CFStringCompare(dev_name, name, 0);
CFRelease(dev_name); CFRelease(dev_name);
if (comparison == kCFCompareEqualTo) { if (comparison == kCFCompareEqualTo) {

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 45; objectVersion = 46;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -17,6 +17,7 @@
8D41064389CC8FD281956BF7 /* fm_op_kernel.cc in Sources */ = {isa = PBXBuildFile; fileRef = 509D811344DB98984FD6C126 /* fm_op_kernel.cc */; }; 8D41064389CC8FD281956BF7 /* fm_op_kernel.cc in Sources */ = {isa = PBXBuildFile; fileRef = 509D811344DB98984FD6C126 /* fm_op_kernel.cc */; };
908EAB1EE59231C41FD88BCD /* ringbuffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 68FD17910F296961541A67E4 /* ringbuffer.cc */; }; 908EAB1EE59231C41FD88BCD /* ringbuffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 68FD17910F296961541A67E4 /* ringbuffer.cc */; };
A16F70FD02394895C6FA7326 /* synth_unit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2082841A11DF6E62596265CF /* synth_unit.cc */; }; A16F70FD02394895C6FA7326 /* synth_unit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2082841A11DF6E62596265CF /* synth_unit.cc */; };
AECC016D16C70F9300FBD4E4 /* patch.cc in Sources */ = {isa = PBXBuildFile; fileRef = AECC016C16C70F9300FBD4E4 /* patch.cc */; };
D5ECD09EBEB1684C00616248 /* resofilter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 97A5CBACD479212282D0BFD6 /* resofilter.cc */; }; D5ECD09EBEB1684C00616248 /* resofilter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 97A5CBACD479212282D0BFD6 /* resofilter.cc */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -30,6 +31,7 @@
8B1FC9FF853D5C32F4771091 /* libcore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcore.a; sourceTree = BUILT_PRODUCTS_DIR; }; 8B1FC9FF853D5C32F4771091 /* libcore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcore.a; sourceTree = BUILT_PRODUCTS_DIR; };
97A5CBACD479212282D0BFD6 /* resofilter.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = resofilter.cc; sourceTree = "<group>"; }; 97A5CBACD479212282D0BFD6 /* resofilter.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = resofilter.cc; sourceTree = "<group>"; };
9FF02D488CE6FD5017D7D81A /* freqlut.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = freqlut.cc; sourceTree = "<group>"; }; 9FF02D488CE6FD5017D7D81A /* freqlut.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = freqlut.cc; sourceTree = "<group>"; };
AECC016C16C70F9300FBD4E4 /* patch.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = patch.cc; sourceTree = "<group>"; };
B73D485E55EBD9CD5950A375 /* env.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = env.cc; sourceTree = "<group>"; }; B73D485E55EBD9CD5950A375 /* env.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = env.cc; sourceTree = "<group>"; };
BA00975977E2704F74104728 /* dx7note.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dx7note.cc; sourceTree = "<group>"; }; BA00975977E2704F74104728 /* dx7note.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dx7note.cc; sourceTree = "<group>"; };
D1D8B6FB01C9E7E2D99378F0 /* sin.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = sin.cc; sourceTree = "<group>"; }; D1D8B6FB01C9E7E2D99378F0 /* sin.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = sin.cc; sourceTree = "<group>"; };
@ -50,6 +52,7 @@
1CE02724939AB46300B24440 = { 1CE02724939AB46300B24440 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
AECC016C16C70F9300FBD4E4 /* patch.cc */,
521E615727EAD5BFC2BFE8C3 /* Source */, 521E615727EAD5BFC2BFE8C3 /* Source */,
ADABDC1FC75C07B5469F92DE /* Products */, ADABDC1FC75C07B5469F92DE /* Products */,
72A5A7469C1AF9FDDAB23BD1 /* Build */, 72A5A7469C1AF9FDDAB23BD1 /* Build */,
@ -119,7 +122,11 @@
}; };
buildConfigurationList = 2F684B8427DC8F5001D9A5B0 /* Build configuration list for PBXProject "core" */; buildConfigurationList = 2F684B8427DC8F5001D9A5B0 /* Build configuration list for PBXProject "core" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 1CE02724939AB46300B24440; mainGroup = 1CE02724939AB46300B24440;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
@ -145,6 +152,7 @@
4FB7FFF436D333023EC91E2C /* sin.cc in Sources */, 4FB7FFF436D333023EC91E2C /* sin.cc in Sources */,
A16F70FD02394895C6FA7326 /* synth_unit.cc in Sources */, A16F70FD02394895C6FA7326 /* synth_unit.cc in Sources */,
80D3C6DC6F5236826B6AB404 /* test_ringbuffer.cc in Sources */, 80D3C6DC6F5236826B6AB404 /* test_ringbuffer.cc in Sources */,
AECC016D16C70F9300FBD4E4 /* patch.cc in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

@ -20,6 +20,7 @@
#include <math.h> #include <math.h>
#include "synth.h" #include "synth.h"
#include "freqlut.h" #include "freqlut.h"
#include "patch.h"
#include "dx7note.h" #include "dx7note.h"
using namespace std; using namespace std;
@ -121,46 +122,48 @@ int ScaleLevel(int midinote, int break_pt, int left_depth, int right_depth,
} }
// Considering making this an init method... // Considering making this an init method...
Dx7Note::Dx7Note(const char patch[128], int midinote, int velocity) { Dx7Note::Dx7Note(const char bulk[128], int midinote, int velocity) {
char patch[156];
UnpackPatch(bulk, patch); // TODO: move this out, take unpacked patch
for (int op = 0; op < 6; op++) { for (int op = 0; op < 6; op++) {
int off = op * 17; int off = op * 21;
int rates[4]; int rates[4];
int levels[4]; int levels[4];
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
rates[i] = patch[off + i]; rates[i] = patch[off + i];
levels[i] = patch[off + 4 + i]; levels[i] = patch[off + 4 + i];
} }
int outlevel = patch[off + 14]; int outlevel = patch[off + 16];
#ifdef VERBOSE #ifdef VERBOSE
for (int j = 8; j < 12; j++) { for (int j = 8; j < 12; j++) {
cout << (int)patch[off + j] << " "; cout << (int)patch[off + j] << " ";
} }
#endif #endif
int level_scaling = ScaleLevel(midinote, patch[off + 8], patch[off + 9], int level_scaling = ScaleLevel(midinote, patch[off + 8], patch[off + 9],
patch[off + 10], patch[off + 11] & 3, patch[off + 11] >> 2); patch[off + 10], patch[off + 11], patch[off + 12]);
outlevel += level_scaling; outlevel += level_scaling;
outlevel = min(99, outlevel); outlevel = min(99, outlevel);
#ifdef VERBOSE #ifdef VERBOSE
cout << op << ": " << level_scaling << " " << outlevel << endl; cout << op << ": " << level_scaling << " " << outlevel << endl;
#endif #endif
outlevel = outlevel << 5; outlevel = outlevel << 5;
outlevel += ScaleVelocity(velocity, patch[off + 13] >> 2); outlevel += ScaleVelocity(velocity, patch[off + 15]);
outlevel = max(0, outlevel); outlevel = max(0, outlevel);
int rate_scaling = ScaleRate(midinote, patch[off + 12] & 7); int rate_scaling = ScaleRate(midinote, patch[off + 13]);
env_[op].init(rates, levels, outlevel, rate_scaling); env_[op].init(rates, levels, outlevel, rate_scaling);
int mode = patch[off + 15] & 1; int mode = patch[off + 17];
int coarse = patch[off + 15] >> 1; int coarse = patch[off + 18];
int fine = patch[off + 16]; int fine = patch[off + 19];
int detune = (patch[off + 12] >> 3) - 7; int detune = patch[off + 20];
int32_t freq = osc_freq(midinote, mode, coarse, fine, detune); int32_t freq = osc_freq(midinote, mode, coarse, fine, detune);
params_[op].freq = freq; params_[op].freq = freq;
// cout << op << " freq: " << freq << endl; // cout << op << " freq: " << freq << endl;
params_[op].phase = 0; params_[op].phase = 0;
params_[op].gain[1] = 0; params_[op].gain[1] = 0;
} }
algorithm_ = patch[110]; algorithm_ = patch[134];
int feedback = patch[111] & 7; int feedback = patch[135];
fb_shift_ = feedback != 0 ? 8 - feedback : 16; fb_shift_ = feedback != 0 ? 8 - feedback : 16;
} }

@ -0,0 +1,51 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstring>
#include "patch.h"
void UnpackPatch(const char bulk[128], char patch[156]) {
for (int op = 0; op < 6; op++) {
// eg rate and level, brk pt, depth, scaling
memcpy(patch + op * 21, bulk + op * 17, 11);
char leftrightcurves = bulk[op * 17 + 11];
patch[op * 21 + 11] = leftrightcurves & 3;
patch[op * 21 + 12] = (leftrightcurves >> 2) & 3;
char detune_rs = bulk[op * 17 + 12];
patch[op * 21 + 13] = detune_rs & 7;
patch[op * 21 + 20] = detune_rs >> 3;
char kvs_ams = bulk[op * 17 + 13];
patch[op * 21 + 14] = kvs_ams & 3;
patch[op * 21 + 15] = kvs_ams >> 2;
patch[op * 21 + 16] = bulk[op * 17 + 14]; // output level
char fcoarse_mode = bulk[op * 17 + 15];
patch[op * 21 + 17] = fcoarse_mode & 1;
patch[op * 21 + 18] = fcoarse_mode >> 1;
patch[op * 21 + 19] = bulk[op * 17 + 16]; // fine freq
}
memcpy(patch + 126, bulk + 102, 9); // pitch env, algo
char oks_fb = bulk[111];
patch[135] = oks_fb & 7;
patch[136] = oks_fb >> 3;
memcpy(patch + 137, bulk + 112, 4); // lfo
char lpms_lfw_lks = bulk[116];
patch[141] = lpms_lfw_lks & 1;
patch[142] = (lpms_lfw_lks >> 1) & 7;
patch[143] = lpms_lfw_lks >> 4;
memcpy(patch + 144, bulk + 117, 11); // transpose, name
patch[155] = 0x3f; // operator on/off
}

@ -0,0 +1,22 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SYNTH_PATCH_H_
#define SYNTH_PATCH_H_
void UnpackPatch(const char bulk[128], char patch[156]);
#endif
Loading…
Cancel
Save