Example #1
0
static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t chan) 
{
	uint8_t val;
	uint8_t i;
	switch (mpu->playbuf[chan].type) 
	{
		case T_OVERFLOW:
			break;
		case T_MARK:
			val=mpu->playbuf[chan].sys_val;
			if (val==0xfc) 
			{
				midi_write(val);
				mpu->state.amask&=~(1<<chan);
				mpu->state.req_mask&=~(1<<chan);
			}
			break;
		case T_MIDI_NORM:
			for (i=0;i<mpu->playbuf[chan].vlength;i++)
				midi_write(mpu->playbuf[chan].value[i]);
			break;
		default:
			break;
	}
}
static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p)
{
        mpu401_uart_t *mpu = (mpu401_uart_t *)p;
        
        if (addr & 1) /*Command*/
        {
                switch (val)
                {
                        case 0xff: /*Reset*/
                        mpu->rx_data = 0xfe; /*Acknowledge*/
                        mpu->status = 0;
                        mpu->uart_mode = 0;
                        break;
                        
                        case 0x3f: /*Enter UART mode*/
                        mpu->rx_data = 0xfe; /*Acknowledge*/
                        mpu->status = 0;
                        mpu->uart_mode = 1;
                        break;
                }
                return;
        }
                        
        /*Data*/
        if (mpu->uart_mode)
                midi_write(val);
}
Example #3
0
static void
sendexclusive(CMMIDI midi, const UINT8 *buf, UINT leng)
{

	CopyMemory(midi->excvbuf, buf, leng);
	midi_write(midi, midi->excvbuf, leng);
	midi->midiexcvwait = 1;
}
Example #4
0
int main(int argc, char *argv[])
{
    struct midi m;
    struct pollfd pt[8];

    if (argc != 2) {
        fprintf(stderr, "usage: %s <device>\n", argv[0]);
        return -1;
    }

    if (midi_open(&m, argv[1]) == -1)
        return -1;

    for (;;) {
        ssize_t z;
        char buf[32];

        z = midi_pollfds(&m, pt, ARRAY_SIZE(pt));
        if (z == -1)
            return -1;

        fputs("poll...\n", stderr);

        if (poll(pt, z, -1) == -1) {
            perror("poll");
            return -1;
        }

        fputs("... return\n", stderr);

        for (;;) {
            size_t n;
            ssize_t z;

            z = midi_read(&m, buf, sizeof buf);
            if (z == -1)
                return -1;
            if (z == 0)
                break;

            for (n = 0; n < z; n++)
                printf(" %02hhx", buf[n]);

            z = midi_write(&m, buf, z);
            printf(" =%d", z);
            if (z == -1)
                return -1;
        }
        printf("\n");

        fflush(stdout);
    }

    midi_close(&m);
}
Example #5
0
static void
midiout_device(CMMIDI midi, UINT32 msg, UINT cnt)
{
	UINT8 buf[3];
	UINT i;

	for (i = 0; i < cnt; i++, msg >>= 8) {
		buf[i] = msg & 0xff;
	}
	waitlastexclusiveout(midi);
	midi_write(midi, buf, cnt);
}
int main (void)
{
    midi_init();

    // Play a chord
    midi_write(Pm_Message(0x90, 60, 100));
    midi_write(Pm_Message(0x90, 64, 100));
    midi_write(Pm_Message(0x90, 67, 100));
    midi_flush();
    
    printf("num_devices: %i\n",Pm_CountDevices());
    PmDeviceID id = Pm_GetDefaultOutputDeviceID();
    const PmDeviceInfo* device = Pm_GetDeviceInfo(id);
    printf("%s\n", device->name);
    
    
    char setchar = '.';
	int channel = 0;
	while (setchar!='\e'){
		scanf(" %c", &setchar);
		//printf("%c\n", setchar);
		switch (setchar){
			case 'z': channel = 0xB0; break;
			case 'x': channel = 0xB1; break;
			case 'c': channel = 0xB2; break;
			case 'v': channel = 0xB3; break;
                // 'q': Pm_WriteShort(midi, 0, Pm_Message(channel, 10, 0)); //button1
                // 'w': Pm_WriteShort(midi, 0, Pm_Message(channel, 11, 0)); //button2
                // 'e': Pm_WriteShort(midi, 0, Pm_Message(channel, 12, 0)); //button3
                // 'r': Pm_WriteShort(midi, 0, Pm_Message(channel, 13, 0)); //button4
			case '1': midi_write(Pm_Message(channel, 0, 0)); midi_flush(); break;
			case '2': midi_write(Pm_Message(channel, 1, 0)); midi_flush(); break;//hand angle
                // '7': Pm_WriteShort(midi, 0, Pm_Message(channel, 7, 0));
                // '8': Pm_WriteShort(midi, 0, Pm_Message(channel, 8, 0));
                // '9': Pm_WriteShort(midi, 0, Pm_Message(channel, 9, 0));
                // '0': Pm_WriteShort(midi, 0, Pm_Message(channel, 10, 0));
			default:
                break;
		}
	}
Example #7
0
static void dspio_process_midi(struct dspio_state *state)
{
    Bit8u data;
    /* no timing for now */
    while (!dspio_midi_output_empty(state)) {
	data = dspio_get_midi_data(state);
	midi_write(data);
    }

    while (midi_get_data_byte(&data)) {
	dspio_put_midi_in_byte(state, data);
	sb_handle_midi_data();
    }
}
Example #8
0
// build and send a midi serial packet
void op_midi_out_cc_send_packet( op_midi_out_cc_t* mout ) {
  u8 pack[3];
  // control change: high nib = 1011 
  pack[0] = 0xb0;
  // low nib = channel
  pack[0] |= (u8)(mout->chan & 0x0f);
  // two data bytes: number, value
  pack[1] = (u8)(mout->num);
  pack[2] = (u8)(mout->val);

  /* print_dbg("\r\n midi_out_cc_send_packet; data: "); */
  /* print_dbg_char_hex(pack[0]);    print_dbg(" "); */
  /* print_dbg_char_hex(pack[1]);    print_dbg(" "); */
  /* print_dbg_char_hex(pack[2]);    print_dbg(" "); */

  midi_write(pack, 3);

}
Example #9
0
// build and send a midi serial packet
void op_midi_out_note_send_packet( op_midi_out_note_t* mout ) {
  u8 pack[3];
  if(mout->vel == 0) {
    // note on/off
    pack[0] = 0x80;
  } else {
    pack[0] = 0x90;
  }
  pack[0] |= (u8)(mout->chan & 0x0f);
  pack[1] = (u8)(mout->num);
  pack[2] = (u8)(mout->vel);

  print_dbg("\r\n midi_out_note_send_packet; data: ");
  print_dbg_char_hex(pack[0]);    print_dbg(" ");
  print_dbg_char_hex(pack[1]);    print_dbg(" ");
  print_dbg_char_hex(pack[2]);    print_dbg(" ");

  midi_write(pack, 3);

}
Example #10
0
static void MPU401_WriteData(mpu_t *mpu, uint8_t val) 
{
	if (mpu->mode==M_UART) {midi_write(val); return;}
	
	switch (mpu->state.command_byte) 
	{	/* 0xe# command data */
		case 0x00:
			break;
		case 0xe0:	/* Set tempo */
			mpu->state.command_byte=0;
			mpu->clock.tempo=val;
			return;
		case 0xe1:	/* Set relative tempo */
			mpu->state.command_byte=0;
			if (val!=0x40) //default value
				pclog("MPU-401:Relative tempo change not implemented\n");
			return;
		case 0xe7:	/* Set internal clock to host interval */
			mpu->state.command_byte=0;
			mpu->clock.cth_rate=val>>2;
			return;
		case 0xec:	/* Set active track mask */
			mpu->state.command_byte=0;
			mpu->state.tmask=val;
			return;
		case 0xed: /* Set play counter mask */
			mpu->state.command_byte=0;
			mpu->state.cmask=val;
			return;
		case 0xee: /* Set 1-8 MIDI channel mask */
			mpu->state.command_byte=0;
			mpu->state.midi_mask&=0xff00;
			mpu->state.midi_mask|=val;
			return;
		case 0xef: /* Set 9-16 MIDI channel mask */
			mpu->state.command_byte=0;
			mpu->state.midi_mask&=0x00ff;
			mpu->state.midi_mask|=((uint16_t)val)<<8;
			return;
		//case 0xe2:	/* Set graduation for relative tempo */
		//case 0xe4:	/* Set metronome */
		//case 0xe6:	/* Set metronome measure length */
		default:
			mpu->state.command_byte=0;
			return;
	}
	static int length,cnt,posd;
	if (mpu->state.wsd) 
	{	/* Directly send MIDI message */
		if (mpu->state.wsd_start) 
		{
			mpu->state.wsd_start=0;
			cnt=0;
				switch (val&0xf0) {
					case 0xc0:case 0xd0:
						mpu->playbuf[mpu->state.channel].value[0]=val;
						length=2;
						break;
					case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0:
						mpu->playbuf[mpu->state.channel].value[0]=val;
						length=3;
						break;
					case 0xf0:
						//pclog("MPU-401:Illegal WSD byte\n");
						mpu->state.wsd=0;
						mpu->state.channel=mpu->state.old_chan;
						return;
					default: /* MIDI with running status */
						cnt++;
						midi_write(mpu->playbuf[mpu->state.channel].value[0]);
				}
		}
		if (cnt<length) {midi_write(val);cnt++;}
		if (cnt==length) {
			mpu->state.wsd=0;
			mpu->state.channel=mpu->state.old_chan;
		}
		return;
	}
	if (mpu->state.wsm) 
	{	/* Directly send system message */
		if (val==MSG_EOX) {midi_write(MSG_EOX);mpu->state.wsm=0;return;}
		if (mpu->state.wsd_start) {
			mpu->state.wsd_start=0;
			cnt=0;
			switch (val) 
			{
				case 0xf2:{ length=3; break;}
				case 0xf3:{ length=2; break;}
				case 0xf6:{ length=1; break;}
				case 0xf0:{ length=0; break;}
				default:
					length=0;
			}
		}
		if (!length || cnt<length) {midi_write(val);cnt++;}
		if (cnt==length) mpu->state.wsm=0;
		return;
	}
	if (mpu->state.cond_req) 
	{ /* Command */
		switch (mpu->state.data_onoff) {
			case -1:
				return;
			case  0: /* Timing byte */
				mpu->condbuf.vlength=0;
				if (val<0xf0) mpu->state.data_onoff++;
				else {
					mpu->state.data_onoff=-1;
					MPU401_EOIHandlerDispatch(mpu);
					return;
				}
				if (val==0) mpu->state.send_now=1;
				else mpu->state.send_now=0;
				mpu->condbuf.counter=val;
				break;
			case  1: /* Command byte #1 */
				mpu->condbuf.type=T_COMMAND;
				if (val==0xf8 || val==0xf9) mpu->condbuf.type=T_OVERFLOW;
				mpu->condbuf.value[mpu->condbuf.vlength]=val;
				mpu->condbuf.vlength++;
				if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch(mpu);
				else mpu->state.data_onoff++;
				break;
			case  2:/* Command byte #2 */
				mpu->condbuf.value[mpu->condbuf.vlength]=val;
				mpu->condbuf.vlength++;
				MPU401_EOIHandlerDispatch(mpu);
				break;
		}
		return;
	}
	switch (mpu->state.data_onoff) 
	{ /* Data */
		case   -1:
			return;
		case    0: /* Timing byte */
			if (val<0xf0) mpu->state.data_onoff=1;
			else {
				mpu->state.data_onoff=-1;
				MPU401_EOIHandlerDispatch(mpu);
				return;
			}
			if (val==0) mpu->state.send_now=1;
			else mpu->state.send_now=0;
			mpu->playbuf[mpu->state.channel].counter=val;
			break;
		case    1: /* MIDI */
			mpu->playbuf[mpu->state.channel].vlength++;
			posd=mpu->playbuf[mpu->state.channel].vlength;
			if (posd==1) {
				switch (val&0xf0) {
					case 0xf0: /* System message or mark */
						if (val>0xf7) {
							mpu->playbuf[mpu->state.channel].type=T_MARK;
							mpu->playbuf[mpu->state.channel].sys_val=val;
							length=1;
						} else {
							//LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message");
							mpu->playbuf[mpu->state.channel].type=T_MIDI_SYS;
							mpu->playbuf[mpu->state.channel].sys_val=val;
							length=1;
						}
						break;
					case 0xc0: case 0xd0: /* MIDI Message */
						mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM;
						length=mpu->playbuf[mpu->state.channel].length=2;
						break;
					case 0x80: case 0x90: case 0xa0:  case 0xb0: case 0xe0: 
						mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM;
						length=mpu->playbuf[mpu->state.channel].length=3;
						break;
					default: /* MIDI data with running status */
						posd++;
						mpu->playbuf[mpu->state.channel].vlength++;
						mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM;
						length=mpu->playbuf[mpu->state.channel].length;
						break;
				}
			}
			if (!(posd==1 && val>=0xf0)) mpu->playbuf[mpu->state.channel].value[posd-1]=val;
			if (posd==length) MPU401_EOIHandlerDispatch(mpu);
	}
}
Example #11
0
static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val)
{	
	uint8_t i;

	if (mpu->state.reset) 
	{
		mpu->state.cmd_pending=val+1;
		return;
	}
	
	if (val<=0x2f) 
	{
		switch (val&3) 
		{ /* MIDI stop, start, continue */
			case 1: {midi_write(0xfc);break;}
			case 2: {midi_write(0xfa);break;}
			case 3: {midi_write(0xfb);break;}
		}
//		if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",(int)val);
		switch (val&0xc) 
		{
			case  0x4:	/* Stop */
				mpu->state.playing=0;
				mpu401_event_callback = 0;
				for (i=0xb0;i<0xbf;i++) 
				{	/* All notes off */
					midi_write(i);
					midi_write(0x7b);
					midi_write(0);
				}
				break;
			case 0x8:	/* Play */
//				LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started");
				mpu->state.playing=1;
				mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * 1000 * TIMER_USEC;
				ClrQueue(mpu);
				break;
		}
	}
	else if (val>=0xa0 && val<=0xa7) 
	{	/* Request play counter */
		if (mpu->state.cmask&(1<<(val&7))) QueueByte(mpu, mpu->playbuf[val&7].counter);
	}
	else if (val>=0xd0 && val<=0xd7) 
	{	/* Send data */
		mpu->state.old_chan=mpu->state.channel;
		mpu->state.channel=val&7;
		mpu->state.wsd=1;
		mpu->state.wsm=0;
		mpu->state.wsd_start=1;
	}
	else
	switch (val) 
	{
		case 0xdf:	/* Send system message */
			mpu->state.wsd=0;
			mpu->state.wsm=1;
			mpu->state.wsd_start=1;
			break;
		case 0x8e:	/* Conductor */
			mpu->state.cond_set=0;
			break;
		case 0x8f:
			mpu->state.cond_set=1;
			break;
		case 0x94: /* Clock to host */
			mpu->clock.clock_to_host=0;
			break;
		case 0x95:
			mpu->clock.clock_to_host=1;
			break;
		case 0xc2: /* Internal timebase */
			mpu->clock.timebase=48;
			break;
		case 0xc3:
			mpu->clock.timebase=72;
			break;
		case 0xc4:
			mpu->clock.timebase=96;
			break;
		case 0xc5:
			mpu->clock.timebase=120;
			break;
		case 0xc6:
			mpu->clock.timebase=144;
			break;
		case 0xc7:
			mpu->clock.timebase=168;
			break;
		case 0xc8:
			mpu->clock.timebase=192;
			break;
		/* Commands with data byte */
		case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: 
		case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef:
			mpu->state.command_byte=val;
			break;
		/* Commands 0xa# returning data */
		case 0xab:	/* Request and clear recording counter */
			QueueByte(mpu, MSG_MPU_ACK);
			QueueByte(mpu, 0);
			return;
		case 0xac:	/* Request version */
			QueueByte(mpu, MSG_MPU_ACK);
			QueueByte(mpu, MPU401_VERSION);
			return;
		case 0xad:	/* Request revision */
			QueueByte(mpu, MSG_MPU_ACK);
			QueueByte(mpu, MPU401_REVISION);
			return;
		case 0xaf:	/* Request tempo */
			QueueByte(mpu, MSG_MPU_ACK);
			QueueByte(mpu, mpu->clock.tempo);
			return;
		case 0xb1:	/* Reset relative tempo */
			mpu->clock.tempo_rel=40;
			break;
		case 0xb9:	/* Clear play map */
		case 0xb8:	/* Clear play counters */
			for (i=0xb0;i<0xbf;i++) 
			{	/* All notes off */
				midi_write(i);
				midi_write(0x7b);
				midi_write(0);
			}
			for (i=0;i<8;i++) 
			{
				mpu->playbuf[i].counter=0;
				mpu->playbuf[i].type=T_OVERFLOW;
			}
			mpu->condbuf.counter=0;
			mpu->condbuf.type=T_OVERFLOW;
			if (!(mpu->state.conductor=mpu->state.cond_set)) mpu->state.cond_req=0;
			mpu->state.amask=mpu->state.tmask;
			mpu->state.req_mask=0;
			mpu->state.irq_pending=1;
			break;
		case 0xff:	/* Reset MPU-401 */
			pclog("MPU-401:Reset %X\n",val);
			mpu401_reset_callback = MPU401_RESETBUSY * 33 * TIMER_USEC;
			mpu->state.reset=1;
			MPU401_Reset(mpu);
#if 0
			if (mpu->mode==M_UART) return;//do not send ack in UART mode
#endif
			break;
		case 0x3f:	/* UART mode */
			pclog("MPU-401:Set UART mode %X\n",val);
			mpu->mode=M_UART;
			break;
		default:;
			//LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val);
	}
	QueueByte(mpu, MSG_MPU_ACK);
}