/* * 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; }
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); }
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 (¤t_time); strtime[strlen(strtime)-1] = '\0'; note->date = str_dup (strtime); finish_note (board, note); }
/* * 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); } }