Esempio n. 1
0
/*
 * Read in one track from the file, and return an element tree
 * describing it.
 * 
 *  Arguments:
 *    msp       - Midi state
 */
static struct trackElement *
read_track(struct midistate *msp)
{
	int  status, laststatus;
	int  head;
	int  length;
	int  delta_time;
	struct trackElement *track;
	int  i;

	laststatus = 0;
	head = read_int(msp, 4);
	if (head != MIDI_TRACK_MAGIC)
		except(formatError,
			"Bad track header (%x), probably not a midi file",
			head);

	length = read_int(msp, 4);
	msp->chunk_size = length;
	msp->chunk_count = 0;	/* nothing read yet */

	track = md_track_new();

	msp->current_time = 0;
	while (msp->chunk_count < msp->chunk_size) {

		delta_time = read_var(msp);
		msp->current_time += delta_time;

		status = read_int(msp, 1);
		if ((status & 0x80) == 0) {
			
			/*
			 * This is not a status byte and so running status is being
			 * used.  Re-use the previous status and push back this byte.
			 */
			put_back(msp, status);
			status = laststatus;
		} else {
			laststatus = status;
		}

		handle_status(msp, track, status);
	}

  restart:
	for (i = 0; i < msp->notes->len; i++) {
		struct noteElement *ns;
		ns = g_ptr_array_index(msp->notes, i);
		msp->device = MD_ELEMENT(ns)->device_channel;
printf("Left over note, finishing\n");
		finish_note(msp, ns->note, 0);
		goto restart;
	}

	msp->track_count++;

	return track;
}
Esempio n. 2
0
void handle_con_note_finish (DESCRIPTOR_DATA *d, char * argument)
{
        char buf[MAX_STRING_LENGTH];
	CHAR_DATA *ch = d->character;
	
		if (!ch->pcdata->in_progress)
		{
			d->connected = CON_PLAYING;
			bug ("nanny: In CON_NOTE_FINISH, but no note in progress",0);
			return;
		}
		switch (tolower(argument[0]))
		{
			case 'c': /* keep writing */
				write_to_buffer (d,"Continuing note...\n\r",0);
				d->connected = CON_NOTE_TEXT;
				break;
			case 'v': /* view note so far */
				if (ch->pcdata->in_progress->text)
				{
					write_to_buffer (d,GREEN "Text of your note so far:" NO_COLOR "\n\r",0);
					write_to_buffer (d, ch->pcdata->in_progress->text, 0);
				}
				else
					write_to_buffer (d,"You haven't written a thing!\n\r\n\r",0);
				write_to_buffer (d, szFinishPrompt, 0);
				write_to_buffer (d, "\n\r",0);
				break;
			case 'p': /* post note */
      if (board_number(ch->pcdata->board) < 4 && is_full_name("all", ch->pcdata->in_progress->to_list)) 
      {
        xprintf(buf,"A new note has been posted by %s on board %d",
          ch->name, board_number(ch->pcdata->board)+1);
        do_info(ch, buf);
      }
				finish_note (ch->pcdata->board, ch->pcdata->in_progress);
				write_to_buffer (d, "Note posted.\n\r",0);
				d->connected = CON_PLAYING;
				ch->pcdata->in_progress = NULL;
				act (BOLD GREEN "$n finishes $s note." NO_COLOR , ch, NULL, NULL, TO_ROOM);
				break;
			case 'f':
				write_to_buffer (d, "Note cancelled!\n\r",0);
				free_note (ch->pcdata->in_progress);
				ch->pcdata->in_progress = NULL;
				d->connected = CON_PLAYING;
				break;
			default: /* invalid response */
				write_to_buffer (d, "Huh? Valid answers are:\n\r\n\r",0);
				write_to_buffer (d, szFinishPrompt, 0);
				write_to_buffer (d, "\n\r",0);
		}
  if (d->connected == CON_PLAYING) REMOVE_BIT(ch->extra, EXTRA_AFK);
}
Esempio n. 3
0
void make_note (const char* board_name, const char *sender, const char *to, const char *subject, const int expire_days, const char *text)
{
	int board_index = board_lookup (board_name);
	BOARD_DATA *board;
	NOTE_DATA *note;
	char *strtime;
	
	if (board_index == BOARD_NOTFOUND)
	{
		bug ("make_note: board not found",0);
		return;
	}
	
	if (strlen2(text) > MAX_NOTE_TEXT)
	{
		bug ("make_note: text too long (%d bytes)", strlen2(text));
		return;
	}
	
	
	board = &boards [board_index];
	
	note = new_note(); /* allocate new note */
	
	note->sender = str_dup (sender);
	note->to_list = str_dup(to);
	note->subject = str_dup (subject);
	note->expire = current_time + expire_days * 60 * 60 * 24;
	note->text = str_dup (text);

	/* convert to ascii. ctime returns a string which last character is \n, so remove that */	
	strtime = ctime (&current_time);
	strtime[strlen(strtime)-1] = '\0';
	
	note->date = str_dup (strtime);
	
	finish_note (board, note);
	
}
Esempio n. 4
0
/*
 * Complete the reading of the status byte. The parsed midi
 * command will be added to the specified track .
 * 
 *  Arguments:
 *    msp       - Current midi file status
 *    track     - Current track
 *    status    - Status byte, ie. current command
 */
static void 
handle_status(struct midistate *msp, struct trackElement *track, int status)
{
	int  ch;
	int  type;
	int  device;
	int  length;
	short note, vel, control;
	int  val;
	unsigned char *data;
	struct element *el;

	ch = status & 0x0f;
	type = status & 0xf0;

	/*
	 * Do not set the device if the type is 0xf0 as these commands are
	 * not channel specific
	 */
	device = 0;
	if (type != 0xf0)
		device = (msp->port<<4) + ch;
	msp->device = device;

	el = NULL;

	switch (type) {	
	case MIDI_NOTE_OFF:
		note = read_int(msp, 1);
		vel = read_int(msp, 1);

		finish_note(msp, note, vel);
		break;

	case MIDI_NOTE_ON:
		note = read_int(msp, 1);
		vel = read_int(msp, 1);

		if (vel == 0) {
			/* This is really a note off */
			finish_note(msp, note, vel);
		} else {
			/* Save the start, so it can be matched with the note off */
			el = save_note(msp, note, vel);
		}
		break;

	case MIDI_KEY_AFTERTOUCH:
		note = read_int(msp, 1);
		vel = read_int(msp, 1);

		/* new aftertouchElement */
		el = MD_ELEMENT(md_keytouch_new(note, vel));
		break;

	case MIDI_CONTROLER:
		control = read_int(msp, 1);
		val = read_int(msp, 1);
		el = MD_ELEMENT(md_control_new(control, val));

		break;
	
	case MIDI_PATCH:
		val = read_int(msp, 1);
		el = MD_ELEMENT(md_program_new(val));
		break;

	case MIDI_CHANNEL_AFTERTOUCH:
		val = read_int(msp, 1);
		el = MD_ELEMENT(md_pressure_new(val));
		break;
	case MIDI_PITCH_WHEEL:
    {
		val = read_int(msp, 1);
        int val2 = read_int(msp, 1);
		val |=  val2 << 7;
		val -= 0x2000;	/* Center it around zero */
		el = MD_ELEMENT(md_pitch_new(val));
		break;
    }
	/* Now for all the non-channel specific ones */
	case 0xf0:
		/* Deal with the end of track event first */
		if (ch == 0x0f) {
			type = read_int(msp, 1);
			if (type == 0x2f) {
				/* End of track - skip to end of real track */
				track->final_time = msp->current_time;
				skip_chunk(msp);
				return;
			}
		}

		/* Get the length of the following data */
		length = read_var(msp);
		data = read_data(msp, length);
		if (ch == 0x0f) {
			el = (struct element *)handle_meta(msp, type, data);
		} else {
			el = (struct element *)md_sysex_new(status, data, length);
		}
		break;
	default:
		except(formatError, "Bad status type 0x%x", type);
		/*NOTREACHED*/
	}

	if (el != NULL) {
		el->element_time = msp->current_time;
		el->device_channel = device;

		md_add(MD_CONTAINER(track), el);
	}
}