Open shooking opened 3 years ago
Hi @mungewell In your experience where does G1X store any checksums in a Sysex? I describe below the format I have found in the B1On. Also should I start my own github and make referenced to yours? Or is there some place I can start to put B1On related cruft?
Been making a few YT vids - trying to ensure I give you/Barsik/SixEight etc credit where due. Great stuff you have done.
So I got a lot of the patch understood now. VERY similar to the other CDR70. Always work in the unpacked space!! SysExTones has done fine work as has sixeight BUT they are working in raw (not cooked!) space.
18 is the magic number for "29" response. Start at byte after 28 - this is your 1st column for overflow bytes. So then 8 bytes on is the next column. Because we are removing one byte per 8 we have a contraction mapping. In the upacked landscape get your decoder to write out 18 bytes in a row. The first 5 are the first 5 FX. It is ID/folder in first 4 bytes. 1st column & 1 == 1 => On. Otherwise off. So in the below this should be consider 0141 so FX is on. the 0e04 I guess is 040e .. and is something like 32 x the folder value. then we have 12 bits per FX. So masking is required.
41 01 00 0e 04 20 00 8c 60 04 00 00 00 00 00 00 00 00
f1 00 00 8c 0d b0 00 2c 40 80 0c 00 00 00 00 00 00 00
21 01 00 12 02 a0 01 28 c0 c7 e9 0b 80 0c 00 00 00 00
41 01 20 ca 02 50 00 0a c0 61 23 0f 60 01 00 00 8a 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 04 00 00 00 20 03 00 00 00 41 2d 52 65 6d 61 72
6b 20 20 00
We can see the last 11 bytes form the name. so this leaves (in above 1st column value 80) 80 00 04 00 00 00 20 03 00 00 00 The 2nd column is the patch volume. I am trying to isolate the next bytes. Tempo? I guess I am looking for per-patch values.
I modified GetCurrentPatch.sh a litle pi@raspberrypi:~/Software/ZoomPedalB1ON $ more ./GetCurrentPatch.sh
#!/bin/bash
export MIDI_DEV=`amidi -l | grep ZOOM | awk '{print $2}'`
# F0 52 00 65 29 00 F7
probeString="F0 52 00 65 29 F7"
echo ${probeString}
theFile=currentPatch.bin
rm ${theFile}
amidi -p ${MIDI_DEV} -S ${probeString} -r ${theFile} -t 1 ; hexdump -C ${theFile
}
the fundamental difference is I write output to currentPatch.bin
Then I read this output into some C++ (code changes as I find more semantics for the bytes)
pi@raspberrypi:~/Software/ZoomPedalB1ON $ more ./B1OnPatchUnpack000.cpp
#include <iostream>
#include <fstream>
#include <iomanip>
#include <iterator>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
typedef unsigned char BYTE;
vector<BYTE> unpack (vector<BYTE> &vi);
vector<BYTE> unpack ( vector<BYTE> &sysex )
{
// Unpack data 7bit to 8bit, MSBs in first byte
//data = bytearray(b"")
int loop = -1;
uint8_t hibits = 0;
int j = 0;
vector<BYTE> unpacked;
// We expect this unpacked sysex to start from byte 5 (0 bias)
for (int i = 5; i < sysex.size() - 1; i++)
{
//byte in packet:
uint8_t byt = sysex[i];
if (loop != -1)
{
uint8_t p = pow (2, loop);
if (hibits & p)
{
byt = 0x80 + byt; //data.append(128 + byte)
unpacked.push_back(byt);
}
else
{
unpacked.push_back(byt);
}
loop = loop - 1;
}
else
{
hibits = byt;
// do we need to acount for short sets (at end of block
block)?
loop = 6;
}
}
// Start to summarize what we know
for (int i = 0; i < 5; i++)
{
int p[] = {
( ( ((unpacked[ 18* i + 4] ) << 8) + (unpacked[18*
i + 3]) ) >> 6 ),
( ( ((unpacked[ 18* i + 6] ) << 8) + (unpacked[18*
i + 5]) ) >> 3 ),
( ( ((unpacked[ 18* i + 8] & 0xF) << 8) + (unpacked[18*
i + 7]) ) ),
( ( ((unpacked[ 18* i + 9] & 0xF) << 8) + (unpacked[18*
i + 8]) ) >> 5 ),
( ( ((unpacked[18* i + 10] & 0xF) << 8) + (unpacked[18*
i + 9]) ) >> 5 ),
( ( ((unpacked[18* i + 11] & 0xF) << 8) + (unpacked[18*
i + 10]) ) >> 5 ),
( ( ((unpacked[18* i + 12] & 0xF) << 8) + (unpacked[18*
i + 11]) ) >> 5 ),
( ( ((unpacked[18* i + 13] & 0xF) << 8) + (unpacked[18*
i + 12]) ) >> 5 )
};
for (j = 0; j < 8; j++)
{
printf("FX%d P%d = %d (%02x) ", i+1, j+1, p[j], p[j]);
}
cout << endl;
}
printf("Volume = %d (%02x)\n", unpacked[91], unpacked[91]);
for (j = 0; j < 10; j++)
{
cout << unpacked[unpacked.size() - 11 + j] ;
}
cout << endl;
return unpacked;
}
vector<BYTE> readFile(char* filename)
{
// open the file:
ifstream file(filename, ios::binary | ios::in);
// Stop eating new lines in binary mode!!!
file.unsetf(ios::skipws);
// get its size:
streampos fileSize;
file.seekg(0, ios::end);
fileSize = file.tellg();
file.seekg(0, ios::beg);
vector<BYTE> vec;
// reserve capacity
vec.reserve(fileSize);
// read the data:
vec.insert(vec.begin(),
istream_iterator<BYTE>(file),
istream_iterator<BYTE>());
// cout << "vec was " << vec.size() << endl;
file.close();
return vec;
}
int
main (int argc, char **argv)
{
/* read the file in, strip off header and F7 */
cout << "Infile: " << argv[1] << endl;
ifstream in_f(argv[1], ios::in | ios::binary);
// ofstream out_f(argv[1], ios::out | ios::binary);
vector<BYTE> vo;
vector<BYTE> vi = readFile(argv[1]);
cout << "INPUT\n";
int ctr = 0;
for(auto i: vi)
{
if (ctr == 5) cout << endl;
if (ctr > 5 && ((ctr - 5) % 16 == 0)) cout << endl;
ctr++;
int value = i;
cout << setfill ('0') << setw (2) << hex << (0xff & (BYTE) value
) << " ";
}
cout << endl;
// cout << "file size: " << vi.size() << endl;
vo = unpack (vi);
ctr = 0;
// we expect 5 x 18 bytes then rest.
cout << "OUTPUT\n";
for (auto i: vo)
{
if (ctr % 18 == 0) cout << endl;
ctr++;
int value = i;
cout << setfill ('0') << setw (2) << hex << (0xff & (BYTE) value
) << " ";
}
cout << endl;
return 0;
}
Currently produces sample output
pi@raspberrypi:~/Software/ZoomPedalB1ON $ ./GetCurrentPatch.sh
F0 52 00 65 29 F7
134 bytes read
00000000 f0 52 00 65 28 00 41 01 00 0e 04 20 00 40 0c 60 |.R.e(.A.... .@.`|
00000010 04 00 00 00 00 04 00 00 00 00 71 00 00 51 0c 0d |..........q..Q..|
00000020 30 00 2c 40 00 00 0c 00 00 00 00 00 00 01 00 21 |0.,@...........!|
00000030 01 00 12 02 20 1d 01 28 40 47 69 0b 00 00 0c 00 |.... ..(@Gi.....|
00000040 00 00 00 41 01 21 20 4a 02 50 00 0a 40 00 61 23 |...A.! J.P..@.a#|
00000050 0f 60 01 00 00 40 0a 00 01 00 00 00 00 00 00 00 |.`...@..........|
00000060 00 00 00 00 00 01 00 00 00 00 00 00 00 00 78 04 |..............x.|
00000070 00 00 00 20 03 00 00 00 00 41 2d 52 65 00 6d 61 |... .....A-Re.ma|
00000080 72 6b 20 20 00 f7 |rk ..|
00000086
pi@raspberrypi:~/Software/ZoomPedalB1ON $ ./B1OnPatchUnpack000 currentPatch.bin
Infile: currentPatch.bin
INPUT
f0 52 00 65 28
00 41 01 00 0e 04 20 00 40 0c 60 04 00 00 00 00
04 00 00 00 00 71 00 00 51 0c 0d 30 00 2c 40 00
00 0c 00 00 00 00 00 00 01 00 21 01 00 12 02 20
1d 01 28 40 47 69 0b 00 00 0c 00 00 00 00 41 01
21 20 4a 02 50 00 0a 40 00 61 23 0f 60 01 00 00
40 0a 00 01 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 78 04 00 00 00 20 03
00 00 00 00 41 2d 52 65 00 6d 61 72 6b 20 20 00
f7
FX1 P1 = 16 (10) FX1 P2 = 4 (04) FX1 P3 = 140 (8c) FX1 P4 = 35 (23) FX1 P5 = 0 (00) FX1 P6 = 0 (00) FX1 P7 = 0 (00) FX1 P8 = 0 (00)
FX2 P1 = 54 (36) FX2 P2 = 22 (16) FX2 P3 = 44 (2c) FX2 P4 = 2 (02) FX2 P5 = 100 (64) FX2 P6 = 0 (00) FX2 P7 = 0 (00) FX2 P8 = 0 (00)
FX3 P1 = 8 (08) FX3 P2 = 52 (34) FX3 P3 = 40 (28) FX3 P4 = 62 (3e) FX3 P5 = 78 (4e) FX3 P6 = 95 (5f) FX3 P7 = 0 (00) FX3 P8 = 100 (64)
FX4 P1 = 11 (0b) FX4 P2 = 10 (0a) FX4 P3 = 10 (0a) FX4 P4 = 14 (0e) FX4 P5 = 27 (1b) FX4 P6 = 121 (79) FX4 P7 = 0 (00) FX4 P8 = 11 (0b)
FX5 P1 = 0 (00) FX5 P2 = 0 (00) FX5 P3 = 0 (00) FX5 P4 = 0 (00) FX5 P5 = 0 (00) FX5 P6 = 0 (00) FX5 P7 = 0 (00) FX5 P8 = 0 (00)
Volume = 120 (78)
A-Remark
OUTPUT
41 01 00 0e 04 20 00 8c 60 04 00 00 00 00 00 00 00 00
f1 00 00 8c 0d b0 00 2c 40 80 0c 00 00 00 00 00 00 00
21 01 00 12 02 a0 01 28 c0 c7 e9 0b 80 0c 00 00 00 00
41 01 20 ca 02 50 00 0a c0 61 23 0f 60 01 00 00 8a 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 78 04 00 00 00 20 03 00 00 00 41 2d 52 65 6d 61 72
6b 20 20 00
In your experience where does G1X store any checksums in a Sysex?
For the G1Four, and friends, the Patch SysEx is checksum'ed at the packed level (as read by Midi). This is a CRC32: https://github.com/mungewell/zoom-zt2/blob/master/zoomzt2.py#L383
I don't believe the unpacked 'ZPTC' patch contains a checksum, however I don't have experience of re-encoding values and uploading to a device. I have achieved some milestones in my other project(s) and have more experience with Construct now... so may revisit my code to fix the 'build' issue for EDTB section.
WRT G1Xon going forward; you are using an lot of C++ code which is outside my ideas for this project. It might be best if you fire up a project for it, I'm happy to share information and help where I can... Cheers, Simon.
OK makes sense. I used the C++ simply because other user was using it. I can use Python (you notice most of stuff is Bash). And in the limit when I move to Ctrlr it will become Lua.
I will create a GIT to record info for folks who are interested in the B1ON.
On Sun, Jan 31, 2021 at 5:29 PM mungewell notifications@github.com wrote:
In your experience where does G1X store any checksums in a Sysex?
For the G1Four, and friends, the Patch SysEx is checksum'ed at the packed level (as read by Midi). This is a CRC32: https://github.com/mungewell/zoom-zt2/blob/master/zoomzt2.py#L383
I don't believe the unpacked 'ZPTC' patch contains a checksum, however I don't have experience of re-encoding values and uploading to a device. I have achieved some milestones in my other project(s) and have more experience with Construct now... so may revisit my code to fix the 'build' issue for EDTB section.
WRT G1Xon going forward; you are using an lot of C++ code which is outside my ideas for this project. It might be best if you fire up a project for it, I'm happy to share information and help where I can... Cheers, Simon.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mungewell/zoom-zt2/issues/24#issuecomment-770418002, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFO7EVYXYLI5HZR4SWWHSQLS4WHQ5ANCNFSM4WO6UG7A .
In your experience where does G1X store any checksums in a Sysex?
For the G1Four, and friends, the Patch SysEx is checksum'ed at the packed level (as read by Midi). This is a CRC32: https://github.com/mungewell/zoom-zt2/blob/master/zoomzt2.py#L383
I don't believe the unpacked 'ZPTC' patch contains a checksum, however I don't have experience of re-encoding values and uploading to a device. I have achieved some milestones in my other project(s) and have more experience with Construct now... so may revisit my code to fix the 'build' issue for EDTB section.
WRT G1Xon going forward; you are using an lot of C++ code which is outside my ideas for this project. It might be best if you fire up a project for it, I'm happy to share information and help where I can... Cheers, Simon.
Hallo Simon I finally did it. https://github.com/shooking/ZoomPedalFun I have tried to give due credit to you, Barsik, SixEight and a load of other folks.
What I am doing now is gradually staging my commits to my new project. Combo of Wiki (like I wanted to do here) so folks can simply read a distilled reference. Links to others work (like your, Barsik etc). Links to my YT videos as I share how I go about the reverse engineering. And hopefully some areas if people want to collaborate.
For example right now based on the work we did with DKS2000 on another thread I have added a lot of additional B1On automation.
The C++ I modified based on your Python is revealing more stuff. zB according to SixEight if you send
9) Set effect type:
Selecting effect from the editor:
selecting Comp in slot 6 sends F0 52 00 5A 31 05 01 17 00 F7,
selecting MComp in slot 6 sends F0 52 00 5A 31 05 01 19 00 F7,
selecting ZNR: F0 52 00 5A 31 05 01 1B 00 F7
selecting Pedal pitch: F0 52 00 5A 31 00 01 45 00 F7
So the 8th byte is the effect type.
This is consistent with the effect type list below: 17hex = 23 dec
Hmmh change the 5A to 65 for a B1On ... it doesnt do anything. Or does it? Well I send the commands in a dual loop. And the pedal doesnt respond anything. BUT ... if I then grab the current patch I can see I AM updating bytes in the pedal!!!
So now I can spy on what is is doing. Neat eh?
I will be sharing this on my Wiki's etc and I am pretty certain there is read across to the other Zoom pedals.
Getting exciting.
Returns some info about the current patch.
Now I choose a few