Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
07-20-2023, 10:05 AM
Hi.
I am an amateur home accordion player who has used MobileSheets for a number of years now.
I use registrations on my Ketron SD90 a lot and was wondering if it is possible to have MobileSheets change the registrations on the SD90 as the music is displayed on my tablet.
I believe that this function is available on Forscore using an ipad, however I have no desire to change to Forscore or indeed Apple.
If this is possible, could I receive as much information as possible please, on how it can be acheived, additional equipment required (if any) any programming required etc.
I appreciate and look forward to receiving any replies that are submitted,
Thank you.
Fraser Reid
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
Hi.
I am a home accordion player who has used MobileSheets for a number of years now.
I currently have a Scandalli midi accordion hooked up to a Ketron SD90.
My SD90 has numerous registrations programmed into it.
I am trying to find out if there is any way that MobileSheets can
control / change the registrations on the SD90.
If this can be done, woukd it be possible to have as much information as possible please, any additional equipment required, any programing required etc.
I appreciate and look forward to receiving any help, information or guidance on this subject.
Thank you.
Fraser Reid
Posts: 488
Threads: 96
Joined: Sep 2014
Reputation:
3
07-21-2023, 05:33 PM
(This post was last modified: 07-21-2023, 05:34 PM by Rey_a.)
I suppose you would have to first find out from Ketron if and how this can be achieved. (how to connect to the device / which instructions to use to control/change the registratiions)
Once you know that, you could come back here and see/ask if/how this can be impllemented iin MobileSheets.
Rudy
_____________________________________________________
MSI Cubi 5 mini pc with IIyama prolite 24" touchscreen-Windows 11, HP Slate 17-Android 4.4.4, iPad Pro 12.9 gen2-iPadOs16
Yamaha Genos 1, Roland PK-6, Yamaha PSR SX900
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
Hi Rudy.
Thank you for your suggestions.
I actually attempted to contact Ketron on rwo occasions, and didn't receive a reply. That's why I posted this.
However as the saying goes "if at first you don't succeed, try try again".
I will give them another try.
Thank you.
Posts: 13,389
Threads: 302
Joined: Apr 2012
Reputation:
238
I have received emails in the past from users with a Ketron SD90 that successfully configured it to communicate with MobileSheets over MIDI. So I know it does work, however, they did not provide any details on what messages they needed to send. So I'm not able to provide that information unfortunately.
Mike
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
(07-22-2023, 03:51 AM)Zubersoft Wrote: I have received emails in the past from users with a Ketron SD90 that successfully configured it to communicate with MobileSheets over MIDI. So I know it does work, however, they did not provide any details on what messages they needed to send. So I'm not able to provide that information unfortunately.
Mike
Hi Mike.
Thank you for that information. I am sure that it can be done, its just finding the correct settings.
It would be nice if one of those previous users noticed this thread and gave me some assistance.
I saw it suggested somewhere earlier tonight that an OTG cable should be used therefore I have ordered an OTG Usb c To USB a adapter which should arrive tomorrow.
I may as well give it a try anyway.
If I am eventually successful, I will update the thread with the solution.
Regards.
Fraser Reid
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
Okay guys.
I have got it working.
I will start by thanking everybody who contributed to this thread who tried to assist me. It is most appreciated.
I do not have time tonight to go into detail however I will try to post my settings tomorrow.
What I can say tonight is that it was a combination of factors that I encountered which I can quickly explain just now.
Because Greg (Ketron forum) asked if I was sure that my tablet was transmitting the midi commands, which I wasn't, I asked on other forums & contacted Samsung to see if my Tab S7+ supported Midi.(I had assumed that it did).
Samsung said it had been removed on the Tab S7+.
Someone on you tube had a video showing how to access the developers menu of the tablet, where I was able to reactivate midi.
I was using the centre USB on the side of the SD90 and it turns out it is either not working properly or it only provides power.
I then tried the tablet cable in another of the ports and the connection showed up on the SD90. That showed some progress.
I then tried various settings on the tablet which I will show tomorrow and I got it working.
Thank you once again.
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
Good morning.
I will attempt to describe how I got the Tab S7+ to send midi commands from Mobile Sheets.
1. Ensure tablet & SD90 are switched on and connected together.
2. Set midi channel to 16
3. Open midi device
4. Select your device. Ketron was not listed, so I chose generic.
5. Open configure figure midi connections
6. Once open tap on the arrow next to midi library and select Google usb.
They turn grey for a second then go back to white.
7. This also opens midi input & output ports below. Tap on both and select your device
8. Return to the normal MobileSheets library page.
9. Long press the title that ypu want to insert the midi commands. A blue check mark will appear next to the title.
10. Press edit song on the top bar and the edit page will appear.
11. Press midi in the top right of the page.
12. Press the + sign at the top right of the white box
13. Press the white arrow next to input port & output port this allows you to select your device.
14. Then at command, above MSB, select the bank number for the SD90
0 = Bank 1
8 = Bank 2
16 = Bank 3
24 = Bank 5
Uncheck LSB
Value patch - enter your registration number
((Some systems the numbering starts at zero. Therefore registration 1 would be 0
registration 2 would be 1 and so on.
Send on song load should be on and coloured blue.
Press the test midi command button and the SD90 should change registration.
Press OK.
The screen will show your command (coloured green) in the white box.
Press OK on the top bar and the song library should reappear
14. Repeat for all registrations.
‐-----------------------------------------------------------------------
I have noticed a couple on anomalies though.
1. I can only go up to 127 registrations per bank, however I believe there was a work around for that. If I get it, I will update the post.
2. I have also noticed that if I am selecting a song from say bank 2 and I am already in bank 1, it occassionally picks the wrong title. It is not the end of the world but if anyone had an ideas great.
I hope that I have not missed anything out and also that it is easily understood.
Than you again to all
Posts: 13,389
Threads: 302
Joined: Apr 2012
Reputation:
238
Thanks for sharing all the details! I'm sure it will be of use to other users.
Mike
Posts: 7
Threads: 1
Joined: Jul 2023
Reputation:
0
Hi.
Just an addition to the above topic.
On Tuesday when I switched my equipment on, the tablet refused to change the registrations on the SD90. I hadn't changed anything and it was working fine on Tuesday afternoon.
After a bit of messing about I discovered that the tablet needs to be powered up before the SD90 or it is not recognised by the SD99.
Cheers
Posts: 29
Threads: 5
Joined: Nov 2023
Reputation:
0
11-28-2023, 02:49 AM
(This post was last modified: 11-28-2023, 04:12 AM by musikus.)
I can only go up to 127 registrations per bank, however I believe there was a work around for that. If I get it, I will update the post.
Every step on the first number will increase the called registry number for 128- 0 = Bank 1 (0-127)
- 1 = Bank 1 (128-255)
- 2 = Bank 1 (255-383)
- 3 = Bank 1 (384-511)
- 4 = Bank 1 (512-639)
- 5 = Bank 1 (640-767)
- 6 = Bank 1 (768-895)
- 7 = Bank 1 (896-end) ...
- 8 = Bank 2 (same system like above)
- ...
- 15 = Bank 2
- 16 = Bank 3
- ....
Posts: 29
Threads: 5
Joined: Nov 2023
Reputation:
0
02-15-2024, 07:14 PM
(This post was last modified: 02-15-2024, 07:24 PM by musikus.)
RegistryBrowser for Ketron SD Series (or Keyboards / Expanders with same File-Structure).
I extended the existing RegistryBrowser (some Ketron users know the tool) and set it up to get the corresponding Program-Change and Control-Change events to be set in MobileSheets.
Maybe it will be useful, if you have a lot of regs to be set up like myself now
Requirement: The app is a JAVA App an need an installed JRE like AZUL JAVA JRE
Download and Help (PDF)
RegistryBrowser
The screenshot shows the function.
For use without the app, you can export the table as csv File.
Hope it helps some people having problems when calculation the events
Posts: 29
Threads: 5
Joined: Nov 2023
Reputation:
0
Maybe the logic could be implemented as a spezial type of MidiEvent in MobileSheets directly.
Code: public class MidiEvent {
private int ketronBankNr = -1;
private int ketronRegNr = -1;
private int pc = -1;
private int cc = -1;
public MidiEvent(int ketronBankNr, int ketronRegisterNr){
if (ketronBankNr>4 | ketronBankNr < 1)
throw new IndexOutOfBoundsException("Registerbank ungültig");
if (ketronRegisterNr > 1000 | ketronRegisterNr < 1)
throw new IndexOutOfBoundsException("Registeriungsnummer ungültig");
this.ketronBankNr = ketronBankNr;
this.ketronRegNr = ketronRegisterNr;
calculateEvent();
}
/**
* @return the pc
*/
public int getPc() {
return pc;
}
/**
* @return the cc
*/
public int getCc() {
return cc;
}
@Override
public String toString(){
return String.format("BANK:%d REG:%d CC:%d PC:%d", ketronBankNr, ketronRegNr, cc, pc);
}
private void calculateEvent(){
int regNr = ketronRegNr -1; // Midi Offset 0; bank Offset 1;
int bankNr = ketronBankNr;
// Bank 1 - 4 => cc 0 = 0, 8, 16, 24
int bank[] = {0, 8, 16, 24};
// ControlChange 00:
// Value 0 - 7 Bank 1
// Value 8 - 15 Bank 2
// Value 16 - 23 Bank 3
// Value 24 - 31 Bank 4
// Regnr 0-127 cc 00 = 0;
// Regnr 128-255 cc 00 = 1;
// Regnr 256-382 cc 00 = 2;
// Regnr 382-509 cc 00 = 3;
// Regnr 509-636 cc 00 = 4;
// Regnr 636-763 cc 00 = 5;
// Regnr 763-890 cc 00 = 6;
// Regnr 890-1000 cc 00 = 7;
// Beim Überlauf über 10xx nächste Bank 8 und offset aus regNr wieder 0;
this.pc = regNr % 128;
this.cc = Math.round(regNr / 128) + bank[bankNr-1];
}
}
Here is the code, I used for mapping Ketron BankNr / RegisterNr to Midi-CC / MIDI_PC
Posts: 13,389
Threads: 302
Joined: Apr 2012
Reputation:
238
The KORG number command is a similar concept - that maps a single number to the expected commands for KORG keyboards, which is actually four control change messages.
With the code you've provided, is the keyboard just expecting a single control change message? Your code uses cc and pc, but a control change has two values in it normally. I just want to make sure I correctly understand.
Although it does require a fair number of changes, if users will benefit from having a new custom MIDI command that just maps the bank number/registration number to a control change message, I can add that. Or I could add a utility that lets users type in the bank number and registration number, and MobileSheets just inserts the necessray values into the control change message for them. This would be much easier to implement, requires fewer changes and is less likely to introduce any issues. I would just add a new MIDI device type selection in the settings for Ketron SD, and an icon for this utility would only show up on the dialog for creating MIDI messages if the device type is set to Ketron SD.
Mike
Posts: 29
Threads: 5
Joined: Nov 2023
Reputation:
0
02-16-2024, 04:53 AM
(This post was last modified: 02-18-2024, 09:23 AM by musikus.)
Hi Mike,
tx for your information.
The two values PC / CC are the values to be set if using the existing way (screenshot mobilesheet midi commands).
Here ist the code i use to fire the complete midi event (using sendmidi console app triggered by java)
The method generating the events is
Code: public ArrayList<String> sendRegistrationChange_SD9(String midiDevice, int registerBank, int registrierungNr){
When running in demo (main method) you get output for sendmidi (commandline tool)
KetronBank:1; KetronRegNr:3; CC:0; PC:2 // The Mapping
/Users/k/Downloads/sendmidi-macos-1.0.13/sendmidi dev MIDI_DEVICE_NAME ch 16 cc 00 0 cc 32 00 pc 2 // the real sendmidi code "MIDI_DEVICE" depends on the device midi is send to
Channel:16 Bank:1 RegNr:2 MidiCommand:/Users/k/Downloads/sendmidi-macos-1.0.13/ sendmidi dev MIDI_DEVICE_NAME ch 16 cc 00 0 cc 32 00 pc 2
That's the command ketron understands.
KetronBank:1; KetronRegNr:3; CC:0; PC:2 // The Mapping
ch 16 cc 00 0 cc 32 00 pc 2 // corresponding Midi command using sendmidi console app
I hope, it's possible to understand my infos
If there is something to test with midi commands, let me know.
Code: /*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package net.gr.midi.midi_sys_ex;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.gr.midi.view.model.Control;
/**
*
* @author k
* Dieses Projekt beinhaltet einen Wrapper, um aus Java heraus System-Exclusive MIDI Daten an ein MIDI-Device zu senden.
* Der eigentliche Transmitter ist das Tool sendmidi
* The project website is https://github.com/gbevin/SendMIDI
*/
public class MIDI_SYS_EX_SENDER {
public boolean test = false;
File SEND_MIDI_PROGRAM = null; // Programm zum Senden der MIDI-SYS-EX Daten
public MIDI_SYS_EX_SENDER(File sendMidi_Program){
SEND_MIDI_PROGRAM = sendMidi_Program;
}
public MIDI_SYS_EX_SENDER(String sendMidi_Program){
SEND_MIDI_PROGRAM = new File(sendMidi_Program);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
MIDI_SYS_EX_SENDER demo = new MIDI_SYS_EX_SENDER("/Users/k/Downloads/sendmidi-macos-1.0.13/sendmidi");
System.out.println("Available MIDI-Interfaces:");
System.out.println(demo.getMidiInterfacesOUT());
// Test
demo.test = true;
for (int bank = 1; bank <=4; bank++){
for (int reg = 1; reg <=10; reg++){
demo.sendRegistrationChange_SD9("", bank, reg);
}
}
}
/**
* Einlesen aller verfügbarer MIDI-Interfaces
* @return Liefert eine Liste der verfügbaren MIDI-Interfaces OUT (aus sicht des PC) zurück.
*/
public ArrayList<String> getMidiInterfacesOUT(){
ArrayList<String> interfaces = new ArrayList<>();
String[] command = new String[2];
command[0] = SEND_MIDI_PROGRAM.getPath();
command[1] = "list";
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null){
interfaces.add(line.trim());
}
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
return interfaces;
}
/**
* Schickt einen kombinierte Note-ON / Note-OFF Event
* @param channel
* @param note
* @param midiDevice
* @param noteOFF true: Note-OFF wird nachgesendet false: nur Note-ON Event wird gesendet.
* @return ArrayList (String) mit Statusmeldungen.
* @throws Exception
*/
public ArrayList<String> sendNoteOnOffEvent(int channel, String note, String midiDevice, boolean noteOFF) throws Exception{
MIDI_TOOLS.get_Note_On_Off_Event(channel, note);
ArrayList<String> cmd = new ArrayList<>();
cmd.add( SEND_MIDI_PROGRAM.getPath() );
cmd.add( "dev" );
cmd.add( midiDevice );
cmd.add("ch");
cmd.add( Integer.toString(channel) );
cmd.add("on");
cmd.add(note);
cmd.add("64");
String commandArray[] = cmd.stream().toArray(String[]::new);
ArrayList<String> retMessage = new ArrayList<>();
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null)
retMessage.add(line);
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
if (noteOFF) {
cmd = new ArrayList<>();
cmd.add(SEND_MIDI_PROGRAM.getPath());
cmd.add("dev");
cmd.add( midiDevice );
cmd.add("ch");
cmd.add(Integer.toString(channel));
cmd.add("off");
cmd.add(note);
cmd.add("0");
rt = Runtime.getRuntime();
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ((line = br.readLine()) != null) {
retMessage.add(line);
}
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
}
return retMessage;
}
/**
* Sende System Exclusiv-Midi-Data aus Datei an das MIDIdevice senden
* @param midiDevice Empfägner MIDI-Interface
* @param sysExFile
* @return Fehlerliste
* @throws Exception
*/
public ArrayList<String> sendMidiSysExFile(String midiDevice, File sysExFile) throws Exception{
// if (!canMIDI_device(MIDIdevice))
// throw new Exception("Das MIDI-Interface " + MIDIdevice + " ist nicht verfügbar.");
ArrayList<String> cmd = new ArrayList<>();
cmd.add( SEND_MIDI_PROGRAM.getPath() );
cmd.add( "dev" );
cmd.add( midiDevice );
cmd.add( "syf" );
cmd.add( sysExFile.getPath() );
String commandArray[] = cmd.stream().toArray(String[]::new);
ArrayList<String> retMessage = new ArrayList<>();
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null)
retMessage.add(line);
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
return retMessage;
}
/**
* Prüfen, ob das übergebene MIDI-Interface verfügbar ist
* @param midiDevice
* @return
* @throws Exception
*/
private boolean canMIDI_device(String midiDevice) {
ArrayList<String> midiInterfaces = getMidiInterfacesOUT();
return midiInterfaces.contains( midiDevice );
}
public ArrayList<String> sendControlChange(String MIDIdevice, int MIDIchannel, int CC, int value){
if (Control.IS_TEST)
System.out.println("Start sendControlChange()");
ArrayList<String> cmd = new ArrayList<>();
cmd.add( SEND_MIDI_PROGRAM.getPath() );
cmd.add( "dev" );
// cmd.add( MIDI_TOOLS.getEscapedDeviceName(MIDIdevice) );
cmd.add( MIDIdevice );
cmd.add( "ch" );
cmd.add( Integer.toString(MIDIchannel) );
cmd.add("cc");
cmd.add( Integer.toString(CC));
cmd.add( Integer.toString(value) );
String commandArray[] = cmd.stream().toArray(String[]::new);
if (Control.IS_TEST){
System.out.println("senControlChange() mit Daten:");
printArray(commandArray);
// return r;
}
ArrayList<String> retMessage = new ArrayList<>();
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null)
retMessage.add(line);
} catch (IOException ex) {
System.out.println("Exception beim Senden des Command: " + ex.getMessage());
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
if (Control.IS_TEST){
System.out.print("Ende sendControlChange()");
for (String s : retMessage)
System.out.println(s);
}
return retMessage;
}
/**
*
* @param MIDIdevice
* @param registerBank
* @param registrierungNr
* @return Statusmeldungen
*/
public ArrayList<String> sendRegistrationChange_SD9(String midiDevice, int registerBank, int registrierungNr){
if (registerBank>4 | registerBank < 1)
throw new IndexOutOfBoundsException("Registerbank ungültig");
if (registrierungNr > 1000 | registrierungNr < 1)
throw new IndexOutOfBoundsException("Registeriungsnummer ungültig");
int regNr = registrierungNr -1;
int regBank = registerBank;
//canMIDI_device(MIDIdevice);
// Bank 1 - 4 => cc 0 = 0, 8, 16, 24
int bank[] = {0, 8, 16, 24};
// ControlChange 00:
// Value 0 - 7 Bank 1
// Value 8 - 15 Bank 2
// Value 16 - 23 Bank 3
// Value 24 - 31 Bank 4
// Regnr 0-127 cc 00 = 0;
// Regnr 128-255 cc 00 = 1;
// Regnr 256-382 cc 00 = 2;
// Regnr 382-509 cc 00 = 3;
// Regnr 509-636 cc 00 = 4;
// Regnr 636-763 cc 00 = 5;
// Regnr 763-890 cc 00 = 6;
// Regnr 890-1000 cc 00 = 7;
// Beim Überlauf über 10xx nächste Bank 8 und offset aus regNr wieder 0;
int cc00 = Math.round(regNr/128);
//System.out.println("cc00: " + cc00);
int pcNr = regNr % 128;
//System.out.println("pcNR: " + pcNr);
ArrayList<String> cmd = new ArrayList<>();
cmd.add( SEND_MIDI_PROGRAM.getPath() );
cmd.add( "dev" );
cmd.add(midiDevice );
cmd.add( "ch" );
cmd.add("16");
cmd.add("cc");
cmd.add("00");
cmd.add(Integer.toString(cc00 + bank[regBank-1]));
cmd.add("cc");
cmd.add("32");
cmd.add("00");
cmd.add("pc");
cmd.add(Integer.toString(pcNr));
String commandArray[] = cmd.stream().toArray(String[]::new);
if (test){
String csv = String.format("KetronBank:%d; KetronRegNr:%d; CC:%d; PC:%d", registerBank, registrierungNr, (cc00 + bank[regBank-1]), pcNr);
System.out.println(csv);
// return null;
System.out.println(String.format("Channel:%s Bank:%s RegNr:%s MidiCommand:%s",16, regBank, regNr, printArray(commandArray) ));
//printArray(commandArray);
ArrayList<String> r = new ArrayList<>();
r.add("Test done");
return r;
}
ArrayList<String> retMessage = new ArrayList<>();
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null)
retMessage.add(line);
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
return retMessage;
}
/**
*
* @param MIDIdevice Empfäger für Sys-Ex MIDI Daten
* @param hex Hex Array für System Exclusiv Meldungen
* @return ArrayList<String%gt; Rückmeldungen aus Konsolenanwendung
* @throws java.lang.Exception
*/
public ArrayList<String> sendMidiSysExCommand(String midiDevice, String[] hex) throws Exception{
if (hex == null)
throw new Exception("Keine MIDI-Daten zum Senden übergeben");
if (hex.length==0)
throw new Exception("Keine MIDI-Daten zum Senden übergeben");
ArrayList<String> cmd = new ArrayList<>();
cmd.add( SEND_MIDI_PROGRAM.getPath() );
cmd.add( "dev" );
cmd.add(midiDevice );
cmd.add("hex" );
cmd.add( "syx" );
cmd.addAll(Arrays.asList(hex));
String commandArray[] = cmd.stream().toArray(String[]::new);
if (test){
printArray(commandArray);
ArrayList<String> r = new ArrayList<>();
r.add("Test done");
return r;
}
ArrayList<String> retMessage = new ArrayList<>();
Runtime rt = Runtime.getRuntime();
Process exec;
try {
exec = rt.exec(commandArray);
BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
String line = "";
while ( (line=br.readLine())!=null)
retMessage.add(line);
} catch (IOException ex) {
Logger.getLogger(MIDI_SYS_EX_SENDER.class.getName()).log(Level.SEVERE, null, ex);
}
return retMessage;
}
/**
* Wandelt den übergebenen String song in einen YAMAHA GENOS Hex String um
* Problem: Umlaute können derzeit nicht korrekt umgesetzt werden.
* @param path
* @param song
* @return MIDI-Befehlt für GENOS
* @throws java.lang.Exception
*/
public String[] getHexValuesGENOS(String path, String song) throws Exception{
checkSpecialChars(song);
String toConvert = "CsR&" +path + "/" + song + ".rgt";
ArrayList<String> hexValues = new ArrayList<>();
for (int i = 0; i< toConvert.length(); i++){
String letter = toConvert.substring(i, i+1);
String hexString = Integer.toHexString( letter.charAt(0));
hexValues.add( getDoubleZero(hexString) );
}
return hexValues.stream().toArray(String[]::new);
}
private String getDoubleZero(String hex){
if (hex.length()==1){
return "0" + hex.toUpperCase();
}
return hex.toUpperCase();
}
/**
* Prüft den String auf Sonderzeichen, Umlaute etc
* @param song
*/
private void checkSpecialChars(String song) throws Exception {
String[] SPECIAL_CHARS = {"ä","ö","ü","ß"};
String search = song.toLowerCase();
for (String s : SPECIAL_CHARS)
if (search.contains(s))
throw new Exception("Unerlaubtes Sonderzeichen im Text enthalten: " + s);
}
private String printArray(String[] arr ){
StringBuilder sb = new StringBuilder();
for (String s : arr){
System.out.print(s);
sb.append(s).append(" ");
System.out.print(" ");
}
System.out.println();
return sb.toString();
}
}
I my java-program i use sendmidi and receivemidi commandline tool because I wasn't able to send/receive midi commands on other way on mac.
|