-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Yamaha FS1r #73
Comments
https://github.com/eclab/edisyn might be helpful, a full editor for (amongst others) the fs1r, Apache 2.0 license |
@markusschloesser The Edisyn docs go into detail about how it does not support Windows very well due to issues with Java MIDI on Windows. :( |
@mslinn I am aware, but mostly had it working a while ago, but yeah, that and the stupid Oracle licensing mess, is meh. |
Actually, the implementation of the adaptations should by now allow to implement the FS1r, even if it is a complex synth. I made a refaceDX adaptation to test the Yamaha protocol, and I think they are all very similar to each other. |
The document can be found at the Yamaha site at https://usa.yamaha.com/files/download/other_assets/4/317954/FS1RE2.PDF |
i tried out the new plugin functionality of chatgpt and asked some (hopefully) good questions, this is the result: |
Hm, not too bad, but also still very generic and not really based on the FS1R. The main challenge with the Yamaha (and Rolands) is to actually understand the data format, as they are so convoluted. We usually want to ignore multi modes and rather just have the synth in single mode, and then determine what parts of the messages make up a single patch. Mostly 4 voices here on the FS1R, but not knowing the synth I have no idea what I am looking at in the documentation, It has 4 different native bulk dumps - but which 4? |
That's very similar to the Roland format with 1 performance and 4 tunes, and potentially sfx and other blocks added. |
Hey, it just took 4 years, but here is a first shot at the Yamaha FS1R. It can load the MIDI files I found in the internet, and it does create separate entries for performance and voice. Which is confusing, and it doesn't help they are all called "Patch" in the property pane. But give it a try, it would already be a success if it can autodetect and you can send programs. I have no idea how to query the edit buffer yet. |
Fantastic! 🤩
PS: did you get my mail on sunday wrt k5000s? |
used another editor (https://synth-voice.sakura.ne.jp) and captured what it was doing: GET system data Sounddiver FS1R edition: this is when it's found: ![]() So FS1R replies with When getting a Performance Bank: ![]() |
ooohhkay. So SD uses a parameter request for detection (with the 0x30, we were using the get settings call. Probably just a speed issue, our message looked correct. Generally, the import commands constructed look good, the main question is about the split of messages. Can you show a MIDI log for importing the edit buffer, and then another one for importing Bank 1, and one for Bank 2? I need to see the answer from the synth. The files I used were MID files (KK can import these alright), and they had strangely very large messages in them. Here is one from Planet Groove website: Here is an adaptation unchanged but with a slower auto detect, that normally should work? |
So I think I need a few more data examples, and we need to decide on the data split. Is one patch always one performance and 4 voices plus voice common? It looks like it, the file above has exactly one performance per voice, and they are even called the same. |
from kk? because request edit buffer doesn't do anything. bank request already further up (#73 (comment))
I have all of those, I cannot get KK to import a single one???
does not work, with only FS1R activated, it looks like this:
shouldn't it send out something with 43 XX 5E? |
ChatGPT: FSeq Data in FS1R SysEx FSeq data is distinct because it contains formant motion data, which is more like a time-based modulation source rather than a traditional patch parameter. How FSeq Data is Handled in SysEx The FS1R allows up to 8 custom FSeqs to be stored in memory. Each FSeq is a complex dataset, including formant amplitude and frequency changes over time. The SysEx bulk dump for FSeq data is much larger than regular voice data due to the detailed time-series information. FSeq SysEx Dump Structure xx refers to the specific FSeq slot (0-7). The size of each FSeq varies, depending on its length and resolution. Extracting & Editing FSeq Data Since Yamaha’s official FS1R editor didn’t expose FSeq editing, most users had to rely on third-party tools or custom SysEx parsing to extract and modify them. The data format isn’t directly compatible with standard audio editors but can be analyzed as a series of control envelope points. xxxxxxxxxxxxxx Yes, to fully reconstruct a performance patch on the FS1R, you need to gather multiple SysEx dumps, as the performance itself does not contain all the necessary voice and FSeq data. Required SysEx Dumps for a Complete FS1R Performance To fully restore a performance, you need:
Sub-ID: 20 Address: 03 00 00 Size: ~128 bytes This contains the performance-level settings, such as effect routing, macro controls, and voice assignments.
Sub-ID: 10 Address: 03 00 00 (for individual voices) Size: ~128 bytes per voice The FS1R’s performance mode allows 4 voices per performance, so you must also dump the specific voices assigned in that performance.
Sub-ID: 50 Address: xx 00 00 (specific FSeq slot) Size: Variable (~8-32 KB per FSeq) If the performance references a custom FSeq (not an internal preset), you need to dump and reload the FSeq data separately. Restoring a Performance from SysEx Dumps To fully reconstruct a performance patch on another FS1R unit:
If the performance uses only the internal preset FSeqs, you don’t need to send FSeq data, as those are stored in ROM. xxxxxxxxxxxxxxx No, the data size for individual voices and performances is larger than 128 bytes. The 128-byte figure was an underestimate. Here’s the correct breakdown: FS1R SysEx Data Sizes So for a full performance setup, you need: 216 bytes for the performance itself. 4 × 1904 bytes for the assigned voices (~7616 bytes total). FSeq dump (if applicable), which can be very large. xxxxxxxxxxxxxx So if I understand correctly, we need to find out if the performance features include an internal or external fseq. If internal it needs a reference. If external, include fseq dump? Which varies in size. Can kk do that? (also K5000r /k5000s has variable sizes) |
Also ChatGPT The Formant Sequence (FSeq) reference—whether it's an internal preset FSeq or a user-defined (external) FSeq—is stored in the Performance SysEx dump. This determines which FSeq is used when playing a performance. Where is the FSeq Reference Stored? Location: Inside the Performance Data SysEx (Sub-ID 20) Data Offset: Byte 48 (0x30 in hex) of the 216-byte Performance Dump Value Range: 00 – 0F (16 possible values) How FSeqs Are Referenced in the Performance SysEx The value at byte 48 (0x30) in the Performance Dump determines which FSeq is used: If the value is 00–07, the FS1R uses one of its built-in FSeqs. Restoring an External FSeq If a performance references an external (user) FSeq (08–0F), then you must also load the correct FSeq SysEx dump (Sub-ID 50). If the corresponding user FSeq isn’t present in RAM, the FS1R may either default to an internal one or fail to play the sequence correctly. |
Autodetect - are you sure you are using the correct module here? It should generate a Yamaha Sysex message, not a generic device ID request. |
Pretty certain, will double check again later. But iirc I just extracted your v2 version into the kk adaptation directory EDIT/Update: @christofmuc I am stupid, I still had an old file (named fs1r instead of yamaha fs1r) in the directory, apologies!! Update 2: with the now real adaptation, I am getting:
Update3: |
the Performance common data references which FSeq it uses, in parameters 15, 16, and 17. We need to find out which are the custom fseq numbers, because only for those we need to store the FSeq, all others are FSeq presets. The Performance Voice data references which Voice is used in parameters 01 and 02, is my guess. There are two different design coices:
We have a precedence for 2: the MKS-80 already archives two tones together with one performance, and the K3 already archives a user wave message together with the patch should the patch need it. Disadvantage of 2: Patches are much bigger (but no problem for the DB), and sending a patch will overwrite a random splash of program slots (unless we allocate and rewrite the positions of voices and fseq separately). Advantage of 2: When you use only KK and don't care about the synth's RAM, this is much easier to use. |
I'd say go for 2, but really only do fseq if user fseq, because they can get big (according to ChatGPT) and transferring via midi might otherwise be too slow |
OK, with the now correct py file:
BUT: not all of it gets stored (successful retrieval message came way too early and pressing "hex dump" shows:
Which is only the PERFORMANCE, but not the VOICES.
|
Ok, it's expected it's not all stored, I just store the performance. I just wanted to see if it buffers the requests so you could request all of once. Seems you can. Why VOICE recall doesn't work surprises me. Can you show the MIDI log from the (non-working) VOICE bank download? We might send out a message, and it might reply with something unexpected? |
👍
09:02:33.151: Out FS1R DIN 7 Sysex [f0 43 20 5e 51 00] |
couple of things about the adaptation:
Would this be correct?
Fuck, it seems that Yamaha didn't implement requesting other than INTERNAL for all 3 types. Neither can one initiate a dump for ROM from the fs1r itself 🙄🤬 |
so chatgpt drew me this nice overview:
Key Points:
ME: |
My head is swimming. Ignoring Fseq for now. So my take so far on idea 2) is: i) An edit buffer always (?) are 5 messages: One performance and 4 voice parts. ii) A performance can reference 0 to 4 user voices.
iii) When loading a bank, we load 128 performances and 128 voices. Those voices might be shared by performances, and there might be non-referenced "orphaned" voices in the bank as well. (Same with the MKS-80). iv) The bank loader will always produce 128 performances of varying size. Orphaned voices will be lost. v) We will not change the storage position of the voices, when sending it to the synth we will send the voices to the original storage locations (which are referenced by the peformance), potentially overwriting the voices of other performances. To improve on that, you need separate bank management for voices and performances. vi) When we convert an edit buffer to a program buffer, we just assign arbitrary voice program positions to the max 4 user voices. When sending that to the synth, a voice is potentially duplicated. vii) When converting a program buffer to an edit buffer, we also need to load each user voice into an edit buffer voice. But how do we send the ROM voices? Do they need to be sent to the synth, or will it pull them from ROM because the performance references the ROM? I hope the latter. |
We cannot send them, because we cannot even get them! More later |
Here is an experimental version that tries to treat the voices as discussed for design 2) - they are just additional data items for performances. Bank import should work. FSeq is ignored for now. You need to install 2.5.2 released just now for the bank import to work. |
alright, as I was using this issue as an idea pad (btw hope thats ok for you?), let me summarize my current thinking and answer your questions:
according to the sysex spec: total 400 Performance Part Parameter (Byte Count : 52 x 4 = 208 bytes ) btw part of that is FSEQ The way I (currently) see it is that we need to parse the Performance first (byte 01), in order to know if Voices are off, internal (and then to be requested) or ROM, in which case we cannot request them and they are just referenced. The same goes for FSEQ (byte 15 and 16) (ah shit, just saw that you wrote exactly this 3 days ago 😂) |
Yes, that's what I implemented! |
immediately crashes kk when trying to request. Nothing in Windows Event Viewer, any way to debug? Edit Buffer request works though. Do you wanna know something that makes the whole thing even more funny/weird/strange? ;-) and one more: If you edit buffer request a ROM Performance in which only Voice 1 is active, the currently implemented request still gets 4 Voices even if they are inactive (don't know which voices it gets) |
Edisyn is able to download the ROM Performances??? I'm gonna try to find out how. |
I would have thought that you could get the ROM via the edit buffer, so I am not surprised - it has to load them in order to play them. Same for all Roland synths (XV- JV- etc) The empty voices - not sure how to detect they are off. They have bank 1 program 0, which I thought must be active. But then, the values are not really documented. Do you have an example of a performance with 1 voice active and another with 4 voices active? Crash - strange, I need to dig. Did you try loading a file? |
If I read that correctly 0 means off |
Yes, that's what I use. But the performances I saw have bank = 1 and program = 0. Which is why I asked for a patch as example. Crash was found, will build 2.5.3 with fix. |
Ah sorry, will provide later (currently watching the little one) |
A001 "Zap !" has Part 1 active with Voice preset "Reso SE", Parts 2,3,4 are off. Edisyn shows this also. Perf Sysex from Edisyn attached Zap-!.zip
which is different to what is in the sysex file above?? (might be too late for me 😇😂) this is what kk gets
The question is if it is relevant? Do you store everything you get? |
Do you plan to do the same?
You do have this file? |
with 2.5.3 and v3 of the adaptation I can request all and it doesn't crash. It takes 20 min (to be expected), but then shows: |
I have looked at this forwards and backwards, and can't find the problem. The requests are good, the data is good, it loads when I subject it to the load routine. Something must be off somewhere. What we can do is to be more precise about which voice buffers are required, but that would not make a difference with this download. Scratching head. |
chatgpt says: From the log, I can see that KnobKraft is correctly sending SysEx requests to the Yamaha FS1R and receiving responses. However, the imported data doesn't seem to be recognized correctly in KnobKraft. Possible Issues:
Debugging Steps:
Would you like me to modify the script to add debug output? is this helpful? |
Try this one! |
? |
It works! 😊 💪👍 |
Wow, just like that? It also collects less than 4 voices for the edit buffer if not 4 user voices are used. Then it seems we could extend this whole thing for the fseqs? Basically doing the same thing as for the voices - if they are referenced, request them and store them together with the performance. |
For the ROM banks we need feature #391 |
But it only gets the performances, intentional? |
True - the data shows none of the patches retrieved references the voice bank 1. They reference voices all over the place (0, 2, 3, 4, 5, 9, 11, 12) but not a single program uses bank 1 (user voice). Can this be? |
probably, will edit on synth and then request, but we might have another problem. I imported the 512 presets that edisyn edit buffer requested. kk shows
|
Moreover: We can also implement two different bank download methods, once to iterate over program buffers and fetch only voices that are referenced (current mode), and secondly to just collect 128 performances and 128 voices, and import spare voices as single voice dumps. Then we have different types of patches inside the database, will make things more interesting. We need #391 to allow that, and we need #306 to allow building the 256 messages from a list of performances with their voices, with automatic memory management for the voices. |
Released the current version with 2.6.0. What is missing apart from the fseq data? |
The documentation is available, e.g. here: https://soundprogramming.net/manuals/Yamaha_FS1R_DataList.pdf
The FS1r also mimicks as a DX7, so maybe that should be done first.
It is currently not possible as an adaptation, but we need the code that I made for the refaceDX, which is a Yamaha and uses the exact same concept of addresses and stream dumps. So this is on hold until we get the right capability implemented.
The text was updated successfully, but these errors were encountered: