Example #1
0
/**
 * Iterate the existing settings defined in a settings object, calling the
 * provided callback function for each setting.
 *
 * @param settings a settings object
 * @param data any user provided pointer
 * @param func callback function to be called on each iteration
 *
 * NOTE: Starting with FluidSynth 1.1.0 the \a func callback is called for each
 * setting in alphabetical order.  Sort order was undefined in previous versions.
 */
void
fluid_settings_foreach (fluid_settings_t* settings, void* data,
                        fluid_settings_foreach_t func)
{
  fluid_settings_foreach_bag_t bag;
  fluid_setting_node_t *node;
  fluid_list_t *p;
  int r;

  fluid_return_if_fail (settings != NULL);
  fluid_return_if_fail (func != NULL);

  bag.path[0] = 0;
  bag.names = NULL;

  fluid_rec_mutex_lock (settings->mutex);

  /* Add all node names to the bag.names list */
  fluid_hashtable_foreach (settings, fluid_settings_foreach_iter, &bag);

  /* Sort names */
  bag.names = fluid_list_sort (bag.names, fluid_list_str_compare_func);

  /* Loop over names and call the callback */
  for (p = bag.names; p; p = p->next)
  {
    r = fluid_settings_get (settings, (char *)(p->data), &node);
    if (r && node) (*func) (data, (char *)(p->data), node->type);
    FLUID_FREE (p->data);       /* -- Free name */
  }

  fluid_rec_mutex_unlock (settings->mutex);

  delete_fluid_list (bag.names);        /* -- Free names list */
}
Example #2
0
/**
 * delete_fluid_hashtable:
 * @hashtable: a #fluid_hashtable_t.
 *
 * Destroys all keys and values in the #fluid_hashtable_t and decrements its
 * reference count by 1. If keys and/or values are dynamically allocated,
 * you should either free them first or create the #fluid_hashtable_t with destroy
 * notifiers using fluid_hashtable_new_full(). In the latter case the destroy
 * functions you supplied will be called on all keys and values during the
 * destruction phase.
 **/
void
delete_fluid_hashtable (fluid_hashtable_t *hashtable)
{
  fluid_return_if_fail (hashtable != NULL);
  fluid_return_if_fail (hashtable->ref_count > 0);

  fluid_hashtable_remove_all (hashtable);
  fluid_hashtable_unref (hashtable);
}
Example #3
0
/**
 * fluid_hashtable_unref:
 * @hashtable: a valid #fluid_hashtable_t.
 *
 * Atomically decrements the reference count of @hashtable by one.
 * If the reference count drops to 0, all keys and values will be
 * destroyed, and all memory allocated by the hash table is released.
 * This function is MT-safe and may be called from any thread.
 *
 * Since: 2.10
 **/
void
fluid_hashtable_unref (fluid_hashtable_t *hashtable)
{
  fluid_return_if_fail (hashtable != NULL);
  fluid_return_if_fail (hashtable->ref_count > 0);

  if (fluid_atomic_int_exchange_and_add (&hashtable->ref_count, -1) - 1 == 0)
    {
      fluid_hashtable_remove_all_nodes (hashtable, TRUE);
      FLUID_FREE (hashtable->nodes);
      FLUID_FREE (hashtable);
    }
}
Example #4
0
/*
 * fluid_hashtable_insert_internal:
 * @hashtable: our #fluid_hashtable_t
 * @key: the key to insert
 * @value: the value to insert
 * @keep_new_key: if %TRUE and this key already exists in the table
 *   then call the destroy notify function on the old key.  If %FALSE
 *   then call the destroy notify function on the new key.
 *
 * Implements the common logic for the fluid_hashtable_insert() and
 * fluid_hashtable_replace() functions.
 *
 * Do a lookup of @key.  If it is found, replace it with the new
 * @value (and perhaps the new @key).  If it is not found, create a
 * new node.
 */
static void
fluid_hashtable_insert_internal (fluid_hashtable_t *hashtable, void *key,
                                 void *value, int keep_new_key)
{
  fluid_hashnode_t **node_ptr, *node;
  unsigned int key_hash;

  fluid_return_if_fail (hashtable != NULL);
  fluid_return_if_fail (hashtable->ref_count > 0);

  node_ptr = fluid_hashtable_lookup_node (hashtable, key, &key_hash);

  if ((node = *node_ptr))
    {
      if (keep_new_key)
        {
          if (hashtable->key_destroy_func)
            hashtable->key_destroy_func (node->key);
          node->key = key;
        }
      else
        {
          if (hashtable->key_destroy_func)
            hashtable->key_destroy_func (key);
        }

      if (hashtable->value_destroy_func)
        hashtable->value_destroy_func (node->value);

      node->value = value;
    }
  else
    {
      node = FLUID_NEW (fluid_hashnode_t);

      if (!node)
      {
        FLUID_LOG (FLUID_ERR, "Out of memory");
        return;
      }

      node->key = key;
      node->value = value;
      node->key_hash = key_hash;
      node->next = NULL;

      *node_ptr = node;
      hashtable->nnodes++;
      fluid_hashtable_maybe_resize (hashtable);
    }
}
Example #5
0
static void
iter_remove_or_steal (RealIter *ri, int notify)
{
  fluid_hashnode_t *prev;
  fluid_hashnode_t *node;
  int position;

  fluid_return_if_fail (ri != NULL);
  fluid_return_if_fail (ri->node != NULL);

  prev = ri->prev_node;
  node = ri->node;
  position = ri->position;

  /* pre-advance the iterator since we will remove the node */

  ri->node = ri->node->next;
  /* ri->prev_node is still the correct previous node */

  while (ri->node == NULL)
    {
      ri->position++;
      if (ri->position >= ri->hashtable->size)
	break;

      ri->prev_node = NULL;
      ri->node = ri->hashtable->nodes[ri->position];
    }

  ri->pre_advanced = TRUE;

  /* remove the node */

  if (prev != NULL)
    prev->next = node->next;
  else
    ri->hashtable->nodes[position] = node->next;

  if (notify)
    {
      if (ri->hashtable->key_destroy_func)
	ri->hashtable->key_destroy_func(node->key);
      if (ri->hashtable->value_destroy_func)
	ri->hashtable->value_destroy_func(node->value);
    }

  FLUID_FREE (node);

  ri->hashtable->nnodes--;
}
Example #6
0
/**
 * fluid_hashtable_foreach:
 * @hashtable: a #fluid_hashtable_t.
 * @func: the function to call for each key/value pair.
 * @user_data: user data to pass to the function.
 *
 * Calls the given function for each of the key/value pairs in the
 * #fluid_hashtable_t.  The function is passed the key and value of each
 * pair, and the given @user_data parameter.  The hash table may not
 * be modified while iterating over it (you can't add/remove
 * items). To remove all items matching a predicate, use
 * fluid_hashtable_foreach_remove().
 *
 * See fluid_hashtable_find() for performance caveats for linear
 * order searches in contrast to fluid_hashtable_lookup().
 **/
void
fluid_hashtable_foreach (fluid_hashtable_t *hashtable, fluid_hr_func_t func,
                         void *user_data)
{
  fluid_hashnode_t *node;
  int i;

  fluid_return_if_fail (hashtable != NULL);
  fluid_return_if_fail (func != NULL);

  for (i = 0; i < hashtable->size; i++)
    for (node = hashtable->nodes[i]; node; node = node->next)
      (* func) (node->key, node->value, user_data);
}
Example #7
0
/**
 * fluid_hashtable_iter_init:
 * @iter: an uninitialized #fluid_hashtable_iter_t.
 * @hashtable: a #fluid_hashtable_t.
 *
 * Initializes a key/value pair iterator and associates it with
 * @hashtable. Modifying the hash table after calling this function
 * invalidates the returned iterator.
 * |[
 * fluid_hashtable_iter_t iter;
 * gpointer key, value;
 *
 * fluid_hashtable_iter_init (&iter, hashtable);
 * while (fluid_hashtable_iter_next (&iter, &key, &value)) 
 *   {
 *     /&ast; do something with key and value &ast;/
 *   }
 * ]|
 *
 * Since: 2.16
 **/
void
fluid_hashtable_iter_init (fluid_hashtable_iter_t *iter,
                           fluid_hashtable_t *hashtable)
{
  RealIter *ri = (RealIter *) iter;

  fluid_return_if_fail (iter != NULL);
  fluid_return_if_fail (hashtable != NULL);

  ri->hashtable = hashtable;
  ri->prev_node = NULL;
  ri->node = NULL;
  ri->position = -1;
  ri->pre_advanced = FALSE;
}
Example #8
0
void delete_fluid_dsound_audio_driver(fluid_audio_driver_t* d)
{
  fluid_dsound_audio_driver_t* dev = (fluid_dsound_audio_driver_t*) d;
  fluid_return_if_fail(dev != NULL);

  /* tell the audio thread to stop its loop */
  dev->cont = 0;

  /* wait till the audio thread exits */
  if (dev->thread != 0) {
    if (WaitForSingleObject(dev->thread, 2000) != WAIT_OBJECT_0) {
      /* on error kill the thread mercilessly */
      FLUID_LOG(FLUID_DBG, "Couldn't join the audio thread. killing it.");
      TerminateThread(dev->thread, 0);
    }
  }

  /* release all the allocated ressources */

    FLUID_FREE(dev->format);

  if (dev->sec_buffer != NULL) {
    IDirectSoundBuffer_Stop(dev->sec_buffer);
    IDirectSoundBuffer_Release(dev->sec_buffer);
  }
  if (dev->prim_buffer != NULL) {
    IDirectSoundBuffer_Release(dev->prim_buffer);
  }
  if (dev->direct_sound != NULL) {
    IDirectSound_Release(dev->direct_sound);
  }

  FLUID_FREE(dev);
}
/* Add a reference to a tuning object */
void
fluid_tuning_ref (fluid_tuning_t *tuning)
{
  fluid_return_if_fail (tuning != NULL);

  fluid_atomic_int_inc (&tuning->refcount);
}
Example #10
0
/* Only called by delete_fluid_synth(), so no need to queue a preset free event */
void
delete_fluid_channel(fluid_channel_t* chan)
{
  fluid_return_if_fail(chan != NULL);
  
  fluid_preset_delete_internal (chan->preset);
  FLUID_FREE(chan);
}
Example #11
0
/**
 * fluid_hashtable_steal_all:
 * @hashtable: a #fluid_hashtable_t.
 *
 * Removes all keys and their associated values from a #fluid_hashtable_t
 * without calling the key and value destroy functions.
 *
 * Since: 2.12
 **/
void
fluid_hashtable_steal_all (fluid_hashtable_t *hashtable)
{
  fluid_return_if_fail (hashtable != NULL);

  fluid_hashtable_remove_all_nodes (hashtable, FALSE);
  fluid_hashtable_maybe_resize (hashtable);
}
Example #12
0
/**
 * Delete the provided settings object
 * @param settings a settings object
 */
void
delete_fluid_settings(fluid_settings_t* settings)
{
  fluid_return_if_fail (settings != NULL);

  fluid_rec_mutex_destroy (settings->mutex);
  delete_fluid_hashtable(settings);
}
Example #13
0
static void delete_samplecache_entry(fluid_samplecache_entry_t *entry)
{
    fluid_return_if_fail(entry != NULL);

    FLUID_FREE(entry->filename);
    FLUID_FREE(entry->sample_data);
    FLUID_FREE(entry->sample_data24);
    FLUID_FREE(entry);
}
Example #14
0
/**
 * Set the second parameter portion of a rule.
 * @param rule MIDI router rule
 * @param min Minimum value for rule match
 * @param max Maximum value for rule match
 * @param mul Value which is multiplied by matching event's 2nd parameter value (1.0 to not modify)
 * @param add Value which is added to matching event's 2nd parameter value (0 to not modify)
 * @since 1.1.0
 *
 * The 2nd parameter of an event depends on the type of event.  For note events
 * its the MIDI velocity, for CC events its the control value and for key pressure
 * events its the key pressure value.  All other types lack a 2nd parameter.
 *
 * All applicable 2nd parameters have the range 0-127.
 *
 * The \a min and \a max parameters define a parameter range window to match
 * incoming events to.  If \a min is less than or equal to \a max then an event
 * is matched if its 2nd parameter is within the defined range (including \a min
 * and \a max). If \a min is greater than \a max then rule is inverted and matches
 * everything except in *between* the defined range (so \a min and \a max would match).
 *
 * The \a mul and \a add values are used to modify event 2nd parameter values prior to
 * sending the event, if the rule matches.
 */
void
fluid_midi_router_rule_set_param2 (fluid_midi_router_rule_t *rule, int min, int max,
                                   float mul, int add)
{
  fluid_return_if_fail (rule != NULL);
  rule->par2_min = min;
  rule->par2_max = max;
  rule->par2_mul = mul;
  rule->par2_add = add;
}
Example #15
0
void
delete_fluid_list(fluid_list_t *list)
{
  fluid_list_t *next;
  fluid_return_if_fail(list != NULL);

  while (list) {
    next = list->next;
    FLUID_FREE(list);
    list = next;
  }
}
Example #16
0
void
fluid_settings_init(fluid_settings_t* settings)
{
  fluid_return_if_fail (settings != NULL);

  fluid_synth_settings(settings);
  fluid_shell_settings(settings);
  fluid_player_settings(settings);
  fluid_file_renderer_settings(settings);
  fluid_audio_driver_settings(settings);
  fluid_midi_driver_settings(settings);
}
Example #17
0
/**
 * Get the range of values of an integer setting
 * @param settings a settings object
 * @param name a setting's name
 * @param min setting's range lower limit
 * @param max setting's range upper limit
 */
void
fluid_settings_getint_range(fluid_settings_t* settings, const char *name,
                            int* min, int* max)
{
  fluid_setting_node_t *node;

  fluid_return_if_fail (settings != NULL);
  fluid_return_if_fail (name != NULL);
  fluid_return_if_fail (min != NULL);
  fluid_return_if_fail (max != NULL);

  fluid_rec_mutex_lock (settings->mutex);

  if (fluid_settings_get(settings, name, &node)
      && (node->type == FLUID_INT_TYPE)) {
    fluid_int_setting_t* setting = (fluid_int_setting_t*) node;
    *min = setting->min;
    *max = setting->max;
  }

  fluid_rec_mutex_unlock (settings->mutex);
}
Example #18
0
/**
 * Iterate the available options for a named string setting, calling the provided
 * callback function for each existing option.
 *
 * @param settings a settings object
 * @param name a setting's name
 * @param data any user provided pointer
 * @param func callback function to be called on each iteration
 *
 * NOTE: Starting with FluidSynth 1.1.0 the \a func callback is called for each
 * option in alphabetical order.  Sort order was undefined in previous versions.
 */
void
fluid_settings_foreach_option (fluid_settings_t* settings, const char *name,
                               void* data, fluid_settings_foreach_option_t func)
{
  fluid_setting_node_t *node;
  fluid_str_setting_t *setting;
  fluid_list_t *p, *newlist = NULL;

  fluid_return_if_fail (settings != NULL);
  fluid_return_if_fail (name != NULL);
  fluid_return_if_fail (func != NULL);

  fluid_rec_mutex_lock (settings->mutex);       /* ++ lock */

  if (!fluid_settings_get (settings, name, &node) || node->type != FLUID_STR_TYPE)
  {
    fluid_rec_mutex_unlock (settings->mutex);   /* -- unlock */
    return;
  }

  setting = (fluid_str_setting_t*)node;

  /* Duplicate option list */
  for (p = setting->options; p; p = p->next)
    newlist = fluid_list_append (newlist, fluid_list_get (p));

  /* Sort by name */
  newlist = fluid_list_sort (newlist, fluid_list_str_compare_func);

  for (p = newlist; p; p = p->next)
    (*func)(data, (char *)name, (char *)fluid_list_get (p));

  fluid_rec_mutex_unlock (settings->mutex);   /* -- unlock */

  delete_fluid_list (newlist);
}
Example #19
0
/*
 * delete_fluid_portaudio_driver
 */
void
delete_fluid_portaudio_driver(fluid_audio_driver_t *p)
{
  fluid_portaudio_driver_t* dev = (fluid_portaudio_driver_t*)p;
  PaError err;
  fluid_return_if_fail(dev != NULL);

  /* PortAudio section */
  if (dev->stream) Pa_CloseStream (dev->stream);

  err = Pa_Terminate();

  if (err != paNoError)
    printf ("PortAudio termination error: %s\n", Pa_GetErrorText (err) );

  FLUID_FREE (dev);
}
Example #20
0
/**
 * Delete a MIDI router instance.
 * @param router MIDI router to delete
 * @return Returns #FLUID_OK on success, #FLUID_FAILED otherwise (only if NULL
 *   \a router passed really)
 */
void
delete_fluid_midi_router (fluid_midi_router_t *router)
{
  fluid_midi_router_rule_t *rule;
  fluid_midi_router_rule_t *next_rule;
  int i;

  fluid_return_if_fail (router != NULL);

  for (i = 0; i < FLUID_MIDI_ROUTER_RULE_COUNT; i++)
  {
    for (rule = router->rules[i]; rule; rule = next_rule)
    {
      next_rule = rule->next;
      FLUID_FREE (rule);
    }
  }

  fluid_mutex_destroy (router->rules_mutex);
  FLUID_FREE (router);
}
Example #21
0
/*
 * delete_fluid_sndmgr_audio_driver
 */
void delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p)
{
  fluid_sndmgr_audio_driver_t* dev = (fluid_sndmgr_audio_driver_t*) p;
  fluid_return_if_fail(dev != NULL);

    if (dev->channel != NULL) {
      SndDisposeChannel(dev->channel, 1);
    }
    
    if (dev->doubleCallbackProc != NULL) {
      DisposeRoutineDescriptor(dev->doubleCallbackProc);
    }
    
    if (dev->doubleHeader != NULL)
    {
        FLUID_FREE(dev->doubleHeader->dbhBufferPtr[0]);
        FLUID_FREE(dev->doubleHeader->dbhBufferPtr[1]);
        FLUID_FREE(dev->doubleHeader);
    }
    
    FLUID_FREE(dev->convbuffers[0]);
    FLUID_FREE(dev->convbuffers[1]);
    FLUID_FREE(dev);
}
Example #22
0
/**
 * Free a MIDI router rule.
 * @param rule Router rule to free
 * @since 1.1.0
 *
 * Note that rules which have been added to a router are managed by the router,
 * so this function should seldom be needed.
 */
void
delete_fluid_midi_router_rule (fluid_midi_router_rule_t *rule)
{
  fluid_return_if_fail (rule != NULL);
  FLUID_FREE (rule);
}