[Vm-dev] [commit][3483]
update midi & scratch plugins to support MIDI plugin improvements
commits at squeakvm.org
commits at squeakvm.org
Mon Nov 2 22:31:32 UTC 2015
Revision: 3483
Author: rowledge
Date: 2015-11-02 14:31:32 -0800 (Mon, 02 Nov 2015)
Log Message:
-----------
update midi & scratch plugins to support MIDI plugin improvements
Modified Paths:
--------------
branches/Cog/platforms/unix/plugins/MIDIPlugin/sqUnixMIDIALSA.inc
branches/Cog/platforms/unix/plugins/ScratchPlugin/unixSeriaPort2Ops.c
Modified: branches/Cog/platforms/unix/plugins/MIDIPlugin/sqUnixMIDIALSA.inc
===================================================================
--- branches/Cog/platforms/unix/plugins/MIDIPlugin/sqUnixMIDIALSA.inc 2015-11-02 22:28:52 UTC (rev 3482)
+++ branches/Cog/platforms/unix/plugins/MIDIPlugin/sqUnixMIDIALSA.inc 2015-11-02 22:31:32 UTC (rev 3483)
@@ -30,7 +30,12 @@
* Reformatted for and integrated into Squeak build by: ian at
* squeakland dot oh are gee
*
- * Last edited: 2009-08-19 04:39:12 by piumarta on emilia-2.local
+ * Modified for Scratch on Raspberry Pi by Manabu Sugiura
+ * - Compatibility of MIDI instruments on Raspbian
+ * - YAMAHA NSX-1 and NSX-39
+ * http://yamaha-webmusic.github.io/nsx1-apps/specs/ANMW820A-001-10-j.pdf
+ *
+ * Last edited: 2014-09-17 22:33:32 by manabu on raspberrypi
*/
/*** MIDI Parameters (used with sqMIDIParameter function) ***/
@@ -143,6 +148,33 @@
3, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+/* Phonetic Symbols Buffer for YAMAHA NSX-1 */
+char ps[128];
+int ps_index = 0;
+
+/* Port information Buffers
+
+Sample:
+-MIDI settings
+% acconet -o
+Port Client name Port name
+14:0 Midi Through Midi Through Port-0
+20:0 NSX-39 NSX-39 MIDI 1
+128:0 TiMidity TiMidity port 0
+128:1 TiMidity TiMidity port 1
+128:2 TiMidity TiMidity port 2
+128:3 TiMidity TiMidity port 3
+
+-Port information Buffers
+portIds[14,20,128,128,128,128]
+portNums[0,0,0,1,2,3]
+*/
+
+#define MAX_PORT_COUNT 256
+int portIds[MAX_PORT_COUNT]; // client ids
+int portNums[MAX_PORT_COUNT]; // port numbers
+int portTypes[MAX_PORT_COUNT] = {0}; // now ignore input client
+
static void performMIDICmd(snd_seq_event_t *ev, int cmdByte, int arg1, int arg2);
static void processMIDIByte(snd_seq_event_t *ev, int aByte);
static void startMIDICommand(snd_seq_event_t *ev, int cmdByte);
@@ -155,23 +187,29 @@
*/
int sqMIDIClosePort(int portNum)
{
- int ret= 0;
+ int ret = 0;
+ snd_seq_event_t ev;
- if (portNum == 0)
- {
- if (out_port >= 0)
- ret= snd_seq_delete_simple_port(seq, out_port);
+ if(portTypes[portNum] == 0){
+ if (out_port >= 0) {
+ char all_note_off[] = {MIDI_CMD_CONTROL, 0x7b, 0x00};
+ snd_seq_ev_set_sysex(&ev, sizeof(all_note_off), all_note_off);
+ snd_seq_ev_set_direct(&ev);
+ snd_seq_ev_set_source(&ev, 0);
+ snd_seq_ev_set_dest(&ev, portIds[portNum], 0);
+ snd_seq_event_output(seq, &ev);
+ snd_seq_drain_output(seq);
+ ret = snd_seq_delete_simple_port(seq, out_port);
out_port= -1;
}
- else if (portNum == 1)
- {
- if (in_port >= 0)
+ } else if (portTypes[portNum] == 1) {
+ if (in_port >= 0) {
ret= snd_seq_delete_simple_port(seq, in_port);
in_port= -1;
}
- else
+ } else {
return interpreterProxy->success(false);
-
+ }
return ret;
}
@@ -197,8 +235,40 @@
int sqMIDIGetPortCount(void)
{
DPRINTF("sqMIDIGetPortCount\n");
+ snd_seq_client_info_t *cinfo;
+ snd_seq_port_info_t *pinfo;
+
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_client_info_set_client(cinfo, -1);
+
+ int cap;
+ int count = 0;
+ int client;
+
+ while (snd_seq_query_next_client(seq, cinfo) >= 0 ){
+ client = snd_seq_client_info_get_client(cinfo);
+
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_client(pinfo, client);
+ snd_seq_port_info_set_port(pinfo, -1);
+
+ // while the next port is available
+ while (snd_seq_query_next_port(seq, pinfo) >= 0) {
+ cap = snd_seq_port_info_get_capability(pinfo);
+ // select output ports
+ if ((cap & SND_SEQ_PORT_CAP_SUBS_WRITE) != 0 && snd_seq_client_id(seq) != snd_seq_port_info_get_client(pinfo)) {
+ if (snd_seq_client_id(seq) != snd_seq_port_info_get_client(pinfo)) {
+ if (count < MAX_PORT_COUNT && strcmp(snd_seq_client_info_get_name(cinfo), "Midi Through") != 0) { //skip Midi Through port
+ portIds[count] = snd_seq_port_info_get_client(pinfo);
+ portNums[count] = snd_seq_port_info_get_port(pinfo);
+ count++;
+ }
+ }
+ }
+ }
+ }
success(true);
- return 1;
+ return count;
}
/* Return an integer indicating the directionality of the given
@@ -207,10 +277,11 @@
*/
int sqMIDIGetPortDirectionality(int portNum)
{
- switch (portNum)
+ switch(portTypes[portNum])
{
case 0: return 2;
- case 1: return 1;
+ case 1: return 1; //TODO: modify
+ default: return 0;
}
return interpreterProxy->success(false);
}
@@ -221,17 +292,23 @@
*/
int sqMIDIGetPortName(int portNum, int namePtr, int length)
{
- static char *userName[] = { "out", "in" };
+ int count;
+ snd_seq_client_info_t *cinfo;
+ char name[128];
+ char portNumStr[128];
- if (portNum == 0 || portNum == 1)
- {
- int count= strlen(userName[portNum]);
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_client_info_set_client(cinfo, -1);
+ snd_seq_get_any_client_info(seq, portIds[portNum], cinfo);
+ sprintf(portNumStr, "%d", portNums[portNum]);
+ sprintf(name, "%s <port:%s>", snd_seq_client_info_get_name(cinfo) , portNumStr);
+ count = strlen(name);
if (count > length) count= length;
- memcpy((void *)namePtr, userName, count);
+ memcpy((void *)namePtr, name, count);
+
+ success(true);
return count;
}
- return interpreterProxy->success(false);
-}
/* Open the given port, if possible. If non-zero, readSemaphoreIndex
specifies the index in the external objects array of a semaphore to
@@ -245,9 +322,9 @@
int sqMIDIOpenPort(int portNum, int readSemaIndex, int interfaceClockRate)
{
DPRINTF(("sqMIDIOpenPort(%d, %d, %d)\n", portNum, readSemaIndex, interfaceClockRate));
+ out_port = -1;
int type= SND_SEQ_PORT_TYPE_APPLICATION;
-
- switch (portNum)
+ switch (portTypes[portNum])
{
case 0:
if (out_port < 0)
@@ -259,6 +336,12 @@
success(false);
return 0;
}
+
+ if (snd_seq_connect_to(seq, out_port, portIds[portNum], 0) < 0)
+ {
+ success(false);
+ return 0;
+ }
}
break;
@@ -282,7 +365,7 @@
snd_seq_queue_tempo_t *tempo= 0;
snd_seq_queue_tempo_alloca(&tempo);
snd_seq_queue_tempo_set_tempo(tempo, interfaceClockRate);
- snd_seq_set_queue_tempo(seq, queue, tempo);
+ snd_seq_set_queue_tempo(seq, queue, (snd_seq_queue_tempo_t*)tempo);
success(true);
return 0;
@@ -333,7 +416,7 @@
{
snd_seq_queue_tempo_t *tempo= 0;
snd_seq_queue_tempo_alloca(&tempo);
- snd_seq_get_queue_tempo(seq, queue, &tempo);
+ snd_seq_get_queue_tempo(seq, queue, tempo);
return snd_seq_queue_tempo_get_tempo(tempo) / 1000.0;
}
break;
@@ -380,7 +463,7 @@
snd_seq_queue_tempo_t *tempo= 0;
snd_seq_queue_tempo_alloca(&tempo);
snd_seq_queue_tempo_set_tempo(tempo, 1000.0 * newValue);
- snd_seq_set_queue_tempo(seq, queue, tempo);
+ snd_seq_set_queue_tempo(seq, queue, (snd_seq_queue_tempo_t*)tempo);
}
break;
@@ -420,8 +503,7 @@
*/
int sqMIDIPortWriteFromAt(int portNum, int count, int bufferPtr, int time)
{
- if (portNum == 0)
- {
+ if (portTypes[portNum] == 0 || portTypes[portNum] == 1) {
int i;
snd_seq_event_t ev;
unsigned char *bytePtr= (unsigned char *)bufferPtr;
@@ -449,8 +531,7 @@
int midiInit(void)
{
- if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_INPUT|SND_SEQ_OPEN_OUTPUT, 0) < 0)
- {
+ if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_INPUT|SND_SEQ_OPEN_OUTPUT, 0) < 0) {
success(false);
return 0;
}
@@ -533,6 +614,7 @@
static void processMIDIByte(snd_seq_event_t *ev, int aByte)
{
+ int i;
if (aByte > 247) return; /* skip all real-time messages */
switch (state)
@@ -577,6 +659,8 @@
if (aByte < 128)
{
/* skip a system exclusive data byte */
+ ps[ps_index] = aByte;
+ ps_index++;
}
else
{
@@ -588,6 +672,13 @@
{
processMIDIByte(ev, aByte); /* if not endSysExclusive, byte is the start the next command */
}
+ else{
+ ps[ps_index] = aByte;
+ ps_index++;
+ //ev->type = SND_SEQ_EVENT_SYSEX;
+ snd_seq_ev_set_sysex(ev, ps_index +1 , ps);
+ ps_index = 0;
+ }
}
}
break;
@@ -619,7 +710,11 @@
case 3: /* start a variable length 'system exclusive' command */
/* a system exclusive command clears running status */
lastCmdByte= 0;
+ if(cmdByte == 240){
+ ps[ps_index] = cmdByte;
+ ps_index++;
+ }
state= sysExclusive;
break;
}
-}
+}
\ No newline at end of file
Modified: branches/Cog/platforms/unix/plugins/ScratchPlugin/unixSeriaPort2Ops.c
===================================================================
--- branches/Cog/platforms/unix/plugins/ScratchPlugin/unixSeriaPort2Ops.c 2015-11-02 22:28:52 UTC (rev 3482)
+++ branches/Cog/platforms/unix/plugins/ScratchPlugin/unixSeriaPort2Ops.c 2015-11-02 22:31:32 UTC (rev 3483)
@@ -337,7 +337,7 @@
}
int isSerialPortDev(char *s) {
- return isPrefix("ttyusb", s);
+ return isPrefix("ttyusb", s) || isPrefix("ttyAMA", s);
}
int isPrefix(char *prefix, char *s) {
More information about the Vm-dev
mailing list