Changeset 5089:b6accd8444a9 in roaraudio


Ignore:
Timestamp:
07/11/11 04:55:29 (13 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Fixed endlessloop in MIDI subsystem (Closes: #137)

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5086 r5089  
     1v. 0.4beta8 - ? 
     2        * Fixed endlessloop in MIDI subsystem (Closes: #137) 
     3 
    14v. 0.4beta7 - Sun Jul 10 2011 13:26 CEST 
    25        Prereleases: 0: Mon Jun 20 2011 18:36 CEST 
  • configure

    r5059 r5089  
    648648 : 
    649649else 
    650  WITHOUT_DCOMP="$WITHOUT_DCOMP"' cb midi rdtcs' 
     650 WITHOUT_DCOMP="$WITHOUT_DCOMP"' rdtcs' 
    651651 no_lib_gcrypt=true 
    652652 no_lib_jack=true 
  • roard/midi.c

    r5053 r5089  
    213213} 
    214214 
     215#if 1 
     216static int _cache_to_mes(struct midi_message * mes, unsigned char * data, size_t len, 
     217                         int id, struct roar_stream_server * ss) { 
     218 unsigned char type = *data; 
     219 
     220 ROAR_DBG("_cache_to_mes(*): type=0x%.2X", (unsigned int)type); 
     221 
     222 if (type == MIDI_TYPE_CLOCK_TICK || type == MIDI_TYPE_CLOCK_START || type == MIDI_TYPE_CLOCK_STOP ) { 
     223  if ( len != 1 ) 
     224   return -1; 
     225 
     226  mes->type = type; 
     227 
     228  if ( type == MIDI_TYPE_CLOCK_TICK ) { 
     229// TODO: 
     230   ROAR_STREAM(ss)->pos = ROAR_MATH_OVERFLOW_ADD(ROAR_STREAM(ss)->pos, 1); 
     231  } 
     232 } else { 
     233  mes->type    = type & 0xF0; 
     234  mes->channel = type & 0x0F; 
     235 
     236  switch (mes->type) { 
     237   case MIDI_TYPE_NOTE_ON: 
     238   case MIDI_TYPE_NOTE_OFF: 
     239     if ( len != 3 ) 
     240      return -1; 
     241     roar_midi_note_from_midiid(&(mes->d.note), data[1]); 
     242 
     243     // if velocity is zero we have a NOTE OFF event 
     244     if ( data[2] == 0 ) 
     245      mes->type = MIDI_TYPE_NOTE_OFF; 
     246   case MIDI_TYPE_PA: 
     247   case MIDI_TYPE_CONTROLER: 
     248     mes->kk = data[1]; 
     249     mes->vv = data[2]; 
     250    break; 
     251   case MIDI_TYPE_PROGRAM: 
     252   case MIDI_TYPE_MA: 
     253     if ( len != 2 ) 
     254      return -1; 
     255     mes->vv = data[1]; 
     256    break; 
     257   case MIDI_TYPE_PB: 
     258   case MIDI_TYPE_SYSEX: 
     259     ROAR_WARN("_cache_to_mes(id=%i): Message of Type 0x%.2X (PB or SysEx) not yet supported", id, (unsigned int)type); 
     260     return -1; 
     261    break; 
     262  } 
     263 } 
     264 
     265 switch (mes->type) { 
     266  case MIDI_TYPE_CONTROLER: 
     267    switch (mes->kk) { 
     268     case MIDI_CCE_MAIN_VOL: 
     269       if ( (516 * mes->vv) > 65100 ) { // max volume 
     270        ss->mixer.mixer[mes->channel] = 65535; 
     271       } else { 
     272        ss->mixer.mixer[mes->channel] = 516 * mes->vv; 
     273       } 
     274      break; 
     275    } 
     276   break; 
     277 } 
     278 
     279 ROAR_DBG("_cache_to_mes(*) = 0"); 
     280 return 0; 
     281} 
     282 
     283int midi_conv_midi2mes (int id) { 
     284 struct roar_stream        *   s; 
     285 struct roar_stream_server *  ss; 
     286 size_t have; 
     287 void * bufdata; 
     288 unsigned char * data; 
     289 unsigned char   cache[3]; 
     290 size_t cachepos = 0; 
     291 int sync = 1; 
     292 struct roar_buffer        * buf = NULL; 
     293 struct midi_message       * mes = NULL; 
     294 
     295 if ( g_streams[id] == NULL ) 
     296  return -1; 
     297 
     298 ROAR_DBG("midi_conv_midi2mes(id=%i) = ?", id); 
     299 
     300 s = ROAR_STREAM(ss = g_streams[id]); 
     301 
     302 while (ss->buffer != NULL) { 
     303  if ( roar_buffer_get_len(ss->buffer, &have) == -1 ) 
     304   return -1; 
     305  if ( roar_buffer_get_data(ss->buffer, &bufdata) == -1 ) 
     306   return -1; 
     307  data = bufdata; 
     308 
     309  while (have) { 
     310   if ( !sync ) { 
     311    if ( *data & 0x80 ) { 
     312     cachepos = 0; 
     313     sync = 1; 
     314    } else { 
     315     data++; 
     316     have--; 
     317     continue; 
     318    } 
     319   } 
     320 
     321   if ( (*data & 0x80) && cachepos != 0 ) { 
     322    // submit cache. 
     323 
     324    if ( midi_new_bufmes(&buf, &mes) == -1 ) { 
     325     // this is bad. 
     326     // TODO: handle better. 
     327     return -1; 
     328    } 
     329 
     330    if ( _cache_to_mes(mes, cache, cachepos, id, ss) == -1 ) { 
     331     ROAR_WARN("midi_conv_midi2mes(id=%i): Message can not be parsed.", id); 
     332     roar_buffer_free(buf); 
     333    } else { 
     334     midi_add_buf(id, buf); // FIXME: don't we need error handling here? 
     335    } 
     336 
     337    cachepos = 0; 
     338   } else if ( cachepos == sizeof(cache) ) { 
     339    // lost sync. 
     340    sync = 0; 
     341    continue; 
     342   } 
     343 
     344   ROAR_DBG("midi_conv_midi2mes(id=%i): cache[%u] = 0x%.2X", id, (unsigned int)cachepos, (unsigned int)*data); 
     345   cache[cachepos++] = *data; 
     346   data++; 
     347   have--; 
     348  } 
     349 
     350  roar_buffer_next(&(ss->buffer)); 
     351 } 
     352 
     353 if ( cachepos ) { 
     354  if ( midi_new_bufmes(&buf, &mes) == -1 ) { 
     355   // this is bad. 
     356   // TODO: handle better. 
     357   return -1; 
     358  } 
     359 
     360  if ( _cache_to_mes(mes, cache, cachepos, id, ss) == -1 ) { 
     361   ROAR_WARN("midi_conv_midi2mes(id=%i): Message can not be parsed.", id); 
     362   roar_buffer_free(buf); 
     363  } else { 
     364   midi_add_buf(id, buf); // FIXME: don't we need error handling here? 
     365   cachepos = 0; 
     366  } 
     367 } 
     368 
     369 if ( cachepos ) { 
     370  if ( roar_buffer_new_data(&buf, cachepos, &bufdata) == -1 ) 
     371   return -1; 
     372 
     373  memcpy(bufdata, cache, cachepos); 
     374 
     375  ss->buffer = buf; 
     376 } 
     377 
     378 return 0; 
     379} 
     380#else 
    215381int midi_conv_midi2mes (int id) { 
    216382 void          * bufdata; 
     
    377543 return 0; 
    378544} 
     545#endif 
    379546 
    380547#define _nb  len++; *(d++) 
Note: See TracChangeset for help on using the changeset viewer.