# src/fluid_event.c

    00001 /* FluidSynth - A Software Synthesizer
    00002  *
    00003  * Copyright (C) 2003  Peter Hanappe and others.
    00004  *
    00005  * This library is free software; you can redistribute it and/or
    00006  * modify it under the terms of the GNU Library General Public License
    00007  * as published by the Free Software Foundation; either version 2 of
    00008  * the License, or (at your option) any later version.
    00009  *
    00010  * This library is distributed in the hope that it will be useful, but
    00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013  * Library General Public License for more details.
    00014  *
    00015  * You should have received a copy of the GNU Library General Public
    00016  * License along with this library; if not, write to the Free
    00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    00018  * 02111-1307, USA
    00019  */
    00020
    00021
    00022 /*
    00023  2002 : API design by Peter Hanappe and Antoine Schmitt
    00024  August 2002 : Implementation by Antoine Schmitt as@gratin.org
    00025                as part of the infiniteCD author project
    00026                http://www.infiniteCD.org/
    00027  Oct4.2002 : AS : corrected bug in heap allocation, that caused a crash during sequencer free.
    00028 */
    00029
    00030
    00031 #include "fluid_event_priv.h"
    00032 #include "fluidsynth_priv.h"
    00033
    00034 /***************************************************************
    00035  *
    00036  *                           SEQUENCER EVENTS
    00037  */
    00038
    00039 /* Event alloc/free */
    00040
    00045 fluid_event_t*
    00046 new_fluid_event()
    00047 {
    00048   fluid_event_t* evt;
    00049
    00050   evt = FLUID_NEW(fluid_event_t);
    00051   if (evt == NULL) {
    00052     fluid_log(FLUID_PANIC, "event: Out of memory\n");
    00053     return NULL;
    00054   }
    00055
    00056   FLUID_MEMSET(evt, 0, sizeof(fluid_event_t));
    00057
    00058   // by default, no type
    00059   evt->dest = -1;
    00060   evt->src = -1;
    00061   evt->type = -1;
    00062
    00063   return(evt);
    00064 }
    00065
    00070 void
    00071 delete_fluid_event(fluid_event_t* evt)
    00072 {
    00073
    00074   if (evt == NULL) {
    00075     return;
    00076   }
    00077
    00078   FLUID_FREE(evt);
    00079 }
    00080
    00087 void
    00088 fluid_event_set_time(fluid_event_t* evt, unsigned int time)
    00089 {
    00090         evt->time = time;
    00091 }
    00092
    00098 void
    00099 fluid_event_set_source(fluid_event_t* evt, short src)
    00100 {
    00101         evt->src = src;
    00102 }
    00103
    00109 void
    00110 fluid_event_set_dest(fluid_event_t* evt, short dest)
    00111 {
    00112         evt->dest = dest;
    00113 }
    00114
    00120 void
    00121 fluid_event_timer(fluid_event_t* evt, void* data)
    00122 {
    00123         evt->type = FLUID_SEQ_TIMER;
    00124         evt->data = data;
    00125 }
    00126
    00134 void
    00135 fluid_event_noteon(fluid_event_t* evt, int channel, short key, short vel)
    00136 {
    00137         evt->type = FLUID_SEQ_NOTEON;
    00138         evt->channel = channel;
    00139         evt->key = key;
    00140         evt->vel = vel;
    00141 }
    00142
    00149 void
    00150 fluid_event_noteoff(fluid_event_t* evt, int channel, short key)
    00151 {
    00152         evt->type = FLUID_SEQ_NOTEOFF;
    00153         evt->channel = channel;
    00154         evt->key = key;
    00155 }
    00156
    00165 void
    00166 fluid_event_note(fluid_event_t* evt, int channel, short key, short vel, unsigned int duration)
    00167 {
    00168         evt->type = FLUID_SEQ_NOTE;
    00169         evt->channel = channel;
    00170         evt->key = key;
    00171         evt->vel = vel;
    00172         evt->duration = duration;
    00173 }
    00174
    00180 void
    00181 fluid_event_all_sounds_off(fluid_event_t* evt, int channel)
    00182 {
    00183         evt->type = FLUID_SEQ_ALLSOUNDSOFF;
    00184         evt->channel = channel;
    00185 }
    00186
    00192 void
    00193 fluid_event_all_notes_off(fluid_event_t* evt, int channel)
    00194 {
    00195         evt->type = FLUID_SEQ_ALLNOTESOFF;
    00196         evt->channel = channel;
    00197 }
    00198
    00205 void
    00206 fluid_event_bank_select(fluid_event_t* evt, int channel, short bank_num)
    00207 {
    00208         evt->type = FLUID_SEQ_BANKSELECT;
    00209         evt->channel = channel;
    00210         evt->control = bank_num;
    00211 }
    00212
    00219 void
    00220 fluid_event_program_change(fluid_event_t* evt, int channel, short val)
    00221 {
    00222         evt->type = FLUID_SEQ_PROGRAMCHANGE;
    00223         evt->channel = channel;
    00224         evt->value = val;
    00225 }
    00226
    00235 void
    00236 fluid_event_program_select(fluid_event_t* evt, int channel,
    00237                                                   unsigned int sfont_id, short bank_num, short preset_num)
    00238 {
    00239         evt->type = FLUID_SEQ_PROGRAMSELECT;
    00240         evt->channel = channel;
    00241         evt->duration = sfont_id;
    00242         evt->value = preset_num;
    00243         evt->control = bank_num;
    00244 }
    00245
    00252 void
    00253 fluid_event_any_control_change(fluid_event_t* evt, int channel)
    00254 {
    00255         evt->type = FLUID_SEQ_ANYCONTROLCHANGE;
    00256         evt->channel = channel;
    00257 }
    00258
    00265 void
    00266 fluid_event_pitch_bend(fluid_event_t* evt, int channel, int pitch)
    00267 {
    00268         evt->type = FLUID_SEQ_PITCHBEND;
    00269         evt->channel = channel;
    00270         if (pitch < 0) pitch = 0;
    00271         if (pitch > 16383) pitch = 16383;
    00272         evt->pitch = pitch;
    00273 }
    00274
    00281 void
    00282 fluid_event_pitch_wheelsens(fluid_event_t* evt, int channel, short value)
    00283 {
    00284         evt->type = FLUID_SEQ_PITCHWHHELSENS;
    00285         evt->channel = channel;
    00286         evt->value = value;
    00287 }
    00288
    00295 void
    00296 fluid_event_modulation(fluid_event_t* evt, int channel, short val)
    00297 {
    00298         evt->type = FLUID_SEQ_MODULATION;
    00299         evt->channel = channel;
    00300         if (val < 0) val = 0;
    00301         if (val > 127) val = 127;
    00302         evt->value = val;
    00303 }
    00304
    00311 void
    00312 fluid_event_sustain(fluid_event_t* evt, int channel, short val)
    00313 {
    00314         evt->type = FLUID_SEQ_SUSTAIN;
    00315         evt->channel = channel;
    00316         if (val < 0) val = 0;
    00317         if (val > 127) val = 127;
    00318         evt->value = val;
    00319 }
    00320
    00328 void
    00329 fluid_event_control_change(fluid_event_t* evt, int channel, short control, short val)
    00330 {
    00331         evt->type = FLUID_SEQ_CONTROLCHANGE;
    00332         evt->channel = channel;
    00333         evt->control = control;
    00334         evt->value = val;
    00335 }
    00336
    00343 void
    00344 fluid_event_pan(fluid_event_t* evt, int channel, short val)
    00345 {
    00346         evt->type = FLUID_SEQ_PAN;
    00347         evt->channel = channel;
    00348         if (val < 0) val = 0;
    00349         if (val > 127) val = 127;
    00350         evt->value = val;
    00351 }
    00352
    00359 void
    00360 fluid_event_volume(fluid_event_t* evt, int channel, short val)
    00361 {
    00362         evt->type = FLUID_SEQ_VOLUME;
    00363         evt->channel = channel;
    00364         if (val < 0) val = 0;
    00365         if (val > 127) val = 127;
    00366         evt->value = val;
    00367 }
    00368
    00375 void
    00376 fluid_event_reverb_send(fluid_event_t* evt, int channel, short val)
    00377 {
    00378         evt->type = FLUID_SEQ_REVERBSEND;
    00379         evt->channel = channel;
    00380         if (val < 0) val = 0;
    00381         if (val > 127) val = 127;
    00382         evt->value = val;
    00383 }
    00384
    00391 void
    00392 fluid_event_chorus_send(fluid_event_t* evt, int channel, short val)
    00393 {
    00394         evt->type = FLUID_SEQ_CHORUSSEND;
    00395         evt->channel = channel;
    00396         if (val < 0) val = 0;
    00397         if (val > 127) val = 127;
    00398         evt->value = val;
    00399 }
    00400
    00401
    00402 /*
    00403  * Accessing event data
    00404  */
    00405
    00411 int fluid_event_get_type(fluid_event_t* evt)
    00412 {
    00413         return evt->type;
    00414 }
    00415
    00421 unsigned int fluid_event_get_time(fluid_event_t* evt)
    00422 {
    00423         return evt->time;
    00424 }
    00425
    00431 short fluid_event_get_source(fluid_event_t* evt)
    00432 {
    00433         return evt->src;
    00434 }
    00435
    00441 short fluid_event_get_dest(fluid_event_t* evt)
    00442 {
    00443         return evt->dest;
    00444 }
    00445
    00451 int fluid_event_get_channel(fluid_event_t* evt)
    00452 {
    00453         return evt->channel;
    00454 }
    00455
    00461 short fluid_event_get_key(fluid_event_t* evt)
    00462 {
    00463         return evt->key;
    00464 }
    00465
    00471 short fluid_event_get_velocity(fluid_event_t* evt)
    00472
    00473 {
    00474         return evt->vel;
    00475 }
    00476
    00482 short fluid_event_get_control(fluid_event_t* evt)
    00483 {
    00484         return evt->control;
    00485 }
    00486
    00498 short fluid_event_get_value(fluid_event_t* evt)
    00499 {
    00500         return evt->value;
    00501 }
    00502
    00510 void* fluid_event_get_data(fluid_event_t* evt)
    00511 {
    00512         return evt->data;
    00513 }
    00514
    00522 unsigned int fluid_event_get_duration(fluid_event_t* evt)
    00523 {
    00524         return evt->duration;
    00525 }
    00526
    00535 short fluid_event_get_bank(fluid_event_t* evt)
    00536 {
    00537         return evt->control;
    00538 }
    00539
    00547 int fluid_event_get_pitch(fluid_event_t* evt)
    00548 {
    00549         return evt->pitch;
    00550 }
    00551
    00560 short
    00561 fluid_event_get_program(fluid_event_t* evt)
    00562 {
    00563         return evt->value;
    00564 }
    00565
    00573 unsigned int
    00574 fluid_event_get_sfont_id(fluid_event_t* evt)
    00575 {
    00576         return evt->duration;
    00577 }
    00578
    00579
    00580
    00581 /********************/
    00582 /* heap management  */
    00583 /********************/
    00584
    00585 fluid_evt_heap_t*
    00586 _fluid_evt_heap_init(int nbEvents)
    00587 {
    00588 #ifdef HEAP_WITH_DYNALLOC
    00589
    00590   int i;
    00591   fluid_evt_heap_t* heap;
    00592   fluid_evt_entry *tmp;
    00593
    00594   heap = FLUID_NEW(fluid_evt_heap_t);
    00595   if (heap == NULL) {
    00596     fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
    00597     return NULL;
    00598   }
    00599
    00600   heap->freelist = NULL;
    00601   fluid_mutex_init(heap->mutex);
    00602
    00603   /* LOCK */
    00604   fluid_mutex_lock(heap->mutex);
    00605
    00606   /* Allocate the event entries */
    00607   for (i = 0; i < nbEvents; i++) {
    00608     tmp = FLUID_NEW(fluid_evt_entry);
    00609     tmp->next = heap->freelist;
    00610     heap->freelist = tmp;
    00611   }
    00612
    00613   /* UNLOCK */
    00614   fluid_mutex_unlock(heap->mutex);
    00615
    00616
    00617 #else
    00618         int i;
    00619         fluid_evt_heap_t* heap;
    00620         int siz = 2*sizeof(fluid_evt_entry *) + sizeof(fluid_evt_entry)*nbEvents;
    00621
    00622         heap = (fluid_evt_heap_t *)FLUID_MALLOC(siz);
    00623   if (heap == NULL) {
    00624     fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
    00625     return NULL;
    00626   }
    00627   FLUID_MEMSET(heap, 0, siz);
    00628
    00629   /* link all heap events */
    00630   {
    00631         fluid_evt_entry *tmp = &(heap->pool);
    00632           for (i = 0 ; i < nbEvents - 1 ; i++)
    00633                         tmp[i].next = &(tmp[i+1]);
    00634                 tmp[nbEvents-1].next = NULL;
    00635
    00636                 /* set head & tail */
    00637                 heap->tail = &(tmp[nbEvents-1]);
    00638         heap->head = &(heap->pool);
    00639   }
    00640 #endif
    00641   return (heap);
    00642 }
    00643
    00644 void
    00645 _fluid_evt_heap_free(fluid_evt_heap_t* heap)
    00646 {
    00647 #ifdef HEAP_WITH_DYNALLOC
    00648   fluid_evt_entry *tmp, *next;
    00649
    00650   /* LOCK */
    00651   fluid_mutex_lock(heap->mutex);
    00652
    00653   tmp = heap->freelist;
    00654   while (tmp) {
    00655     next = tmp->next;
    00656     FLUID_FREE(tmp);
    00657     tmp = next;
    00658   }
    00659
    00660   /* UNLOCK */
    00661   fluid_mutex_unlock(heap->mutex);
    00662   fluid_mutex_destroy(heap->mutex);
    00663
    00664   FLUID_FREE(heap);
    00665
    00666 #else
    00667         FLUID_FREE(heap);
    00668 #endif
    00669 }
    00670
    00671 fluid_evt_entry*
    00672 _fluid_seq_heap_get_free(fluid_evt_heap_t* heap)
    00673 {
    00674 #ifdef HEAP_WITH_DYNALLOC
    00675   fluid_evt_entry* evt = NULL;
    00676
    00677   /* LOCK */
    00678   fluid_mutex_lock(heap->mutex);
    00679
    00680 #if !defined(MACOS9)
    00681   if (heap->freelist == NULL) {
    00682     heap->freelist = FLUID_NEW(fluid_evt_entry);
    00683     if (heap->freelist != NULL) {
    00684       heap->freelist->next = NULL;
    00685     }
    00686   }
    00687 #endif
    00688
    00689   evt = heap->freelist;
    00690
    00691   if (evt != NULL) {
    00692     heap->freelist = heap->freelist->next;
    00693     evt->next = NULL;
    00694   }
    00695
    00696   /* UNLOCK */
    00697   fluid_mutex_unlock(heap->mutex);
    00698
    00699   return evt;
    00700
    00701 #else
    00702         fluid_evt_entry* evt;
    00703         if (heap->head == NULL) return NULL;
    00704
    00705         /* take from head of the heap */
    00706         /* critical - should threadlock ? */
    00707         evt = heap->head;
    00708         heap->head = heap->head->next;
    00709
    00710         return evt;
    00711 #endif
    00712 }
    00713
    00714 void
    00715 _fluid_seq_heap_set_free(fluid_evt_heap_t* heap, fluid_evt_entry* evt)
    00716 {
    00717 #ifdef HEAP_WITH_DYNALLOC
    00718
    00719   /* LOCK */
    00720   fluid_mutex_lock(heap->mutex);
    00721
    00722   evt->next = heap->freelist;
    00723   heap->freelist = evt;
    00724
    00725   /* UNLOCK */
    00726   fluid_mutex_unlock(heap->mutex);
    00727
    00728 #else
    00729         /* append to the end of the heap */
    00730         /* critical - should threadlock ? */
    00731         heap->tail->next = evt;
    00732         heap->tail = evt;
    00733         evt->next = NULL;
    00734 #endif
    00735 }