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 }

Generated on Sat Nov 17 13:40:23 2007 for libfluidsynth by  doxygen 1.5.3