Ejemplo n.º 1
0
/**
 * Free a sequencer object.
 * @param seq Sequencer to delete
 */
void
delete_fluid_sequencer (fluid_sequencer_t* seq)
{

	if (seq == NULL) {
		return;
	}

	/* cleanup clients */
	while (seq->clients) {
		fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)seq->clients->data;
		fluid_sequencer_unregister_client(seq, client->id);
	}

	_fluid_seq_queue_end(seq);

/*	if (seq->clients) {
		fluid_list_t *tmp = seq->clients;
		while (tmp != NULL) {
			fluid_sequencer_client_t *client = (fluid_sequencer_client_t*)tmp->data;
			if (client->name) FLUID_FREE(client->name);
			tmp = tmp->next;
		}
		delete_fluid_list(seq->clients);
		seq->clients = NULL;
	}*/

#if FLUID_SEQ_WITH_TRACE
	if (seq->tracebuf != NULL)
		FLUID_FREE(seq->tracebuf);
	seq->tracebuf = NULL;
#endif

	FLUID_FREE(seq);
}
Ejemplo n.º 2
0
void
_fluid_evt_heap_free(fluid_evt_heap_t* heap)
{
#ifdef HEAP_WITH_DYNALLOC
  fluid_evt_entry *tmp, *next;

  /* LOCK */
  fluid_mutex_lock(heap->mutex);

  tmp = heap->freelist;
  while (tmp) {
    next = tmp->next;
    FLUID_FREE(tmp);
    tmp = next;
  }

  /* UNLOCK */
  fluid_mutex_unlock(heap->mutex);
  fluid_mutex_destroy(heap->mutex);

  FLUID_FREE(heap);

#else
	FLUID_FREE(heap);
#endif
}
Ejemplo n.º 3
0
/**
 * Open a MIDI file and return a new MIDI file handle.
 * @internal
 * @param filename Path of file to open.
 * @return New MIDI file handle or NULL on error.
 */
fluid_midi_file* new_fluid_midi_file(char* filename)
{
	fluid_midi_file* mf;

	mf = FLUID_NEW(fluid_midi_file);
	if (mf == NULL) {
		FLUID_LOG(FLUID_ERR, "Out of memory");
		return NULL;
	}
	FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));

	mf->c = -1;
	mf->running_status = -1;
	mf->fp = FLUID_FOPEN(filename, "rb");

	if (mf->fp == NULL) {
		FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file");
		FLUID_FREE(mf);
		return NULL;
	}

	if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
		FLUID_FREE(mf);
		return NULL;
	}
	return mf;
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
/*
 * delete_fluid_portaudio_driver
 */
int
delete_fluid_portaudio_driver(fluid_audio_driver_t *p)
{
  fluid_portaudio_driver_t* dev;
  PaError err;

  dev = (fluid_portaudio_driver_t*)p;
  if (dev == NULL) return FLUID_OK;

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

  err = Pa_Terminate();

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

  if (dev->buffers[0]) {
    FLUID_FREE(dev->buffers[0]);
  }
  if (dev->buffers[1]) {
    FLUID_FREE(dev->buffers[1]);
  }

  FLUID_FREE (dev);
  return FLUID_OK;
}
Ejemplo n.º 6
0
/**
 * Delete a MIDI player instance.
 * @param player MIDI player instance
 * @return Always returns #FLUID_OK
 */
int
delete_fluid_player(fluid_player_t *player)
{
    fluid_list_t *q;
    fluid_playlist_item* pi;

    if (player == NULL) {
        return FLUID_OK;
    }
    fluid_player_stop(player);
    fluid_player_reset(player);

    while (player->playlist != NULL) {
        q = player->playlist->next;
        pi = (fluid_playlist_item*) player->playlist->data;
        FLUID_FREE(pi->filename);
        FLUID_FREE(pi->buffer);
        FLUID_FREE(pi);
        delete1_fluid_list(player->playlist);
        player->playlist = q;
    }

    FLUID_FREE(player);
    return FLUID_OK;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
void delete_fluid_tuning(fluid_tuning_t* tuning)
{
  if (tuning == NULL) {
    return;
  }
  if (tuning->name != NULL) {
    FLUID_FREE(tuning->name);
  }
  FLUID_FREE(tuning);
}
Ejemplo n.º 9
0
/*
 * delete_fluid_track
 */
int delete_fluid_track(fluid_track_t* track)
{
	if (track->name != NULL) {
		FLUID_FREE(track->name);
	}
	if (track->first != NULL) {
		delete_fluid_midi_event(track->first);
	}
	FLUID_FREE(track);
	return FLUID_OK;
}
Ejemplo n.º 10
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);
    }
}
Ejemplo n.º 11
0
/*
 * delete_fluid_midishare_midi_driver
 */
int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p)
{
    fluid_midishare_midi_driver_t* dev;

    dev = (fluid_midishare_midi_driver_t*) p;
    if (dev == NULL) {
        return FLUID_OK;
    }

    if (dev->filter) MidiFreeFilter(dev->filter);

#if defined(MIDISHARE_DRIVER)
    fluid_midishare_close_driver(dev);
#else
    fluid_midishare_close_appl(dev);
#endif

#if defined(MACINTOSH) && defined(MACOS9)
    DisposeRoutineDescriptor(dev->upp_alarm_ptr);
    DisposeRoutineDescriptor(dev->upp_wakeup_ptr);
    DisposeRoutineDescriptor(dev->upp_sleep_ptr);
    DisposeRoutineDescriptor(dev->upp_task_ptr);
#endif

    dev->status = FLUID_MIDI_DONE;

    FLUID_FREE(dev);
    return FLUID_OK;
}
Ejemplo n.º 12
0
/**
 * Remove an option previously assigned by fluid_settings_add_option().
 * @param settings a settings object
 * @param name a setting's name
 * @param s option string to remove
 * @return 1 if the setting exists and option was removed, 0 otherwise
 */
int
fluid_settings_remove_option(fluid_settings_t* settings, const char *name, const char* s)
{
  fluid_setting_node_t *node;
  int retval = 0;

  fluid_return_val_if_fail (settings != NULL, 0);
  fluid_return_val_if_fail (name != NULL, 0);
  fluid_return_val_if_fail (s != NULL, 0);

  fluid_rec_mutex_lock (settings->mutex);

  if (fluid_settings_get(settings, name, &node)
      && (node->type == FLUID_STR_TYPE)) {

    fluid_str_setting_t* setting = (fluid_str_setting_t*) node;
    fluid_list_t* list = setting->options;

    while (list) {
      char* option = (char*) fluid_list_get(list);
      if (FLUID_STRCMP(s, option) == 0) {
	FLUID_FREE (option);
	setting->options = fluid_list_remove_link(setting->options, list);
	retval = 1;
        break;
      }
      list = fluid_list_next(list);
    }
  }

  fluid_rec_mutex_unlock (settings->mutex);

  return retval;
}
Ejemplo n.º 13
0
int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p)
{
    fluid_dart_audio_driver_t* dev = (fluid_dart_audio_driver_t*) p;

    if (dev == NULL) {
        return FLUID_OK;
    }

    if (dev->usDeviceID != 0) {
        MCI_GENERIC_PARMS    GenericParms;

        /* Send message to stop the audio device
         */
        m_pfnmciSendCommand(dev->usDeviceID, MCI_STOP, MCI_WAIT,
                            (PVOID)&GenericParms, 0);

        /* Deallocate device buffers
         */
        m_pfnmciSendCommand(dev->usDeviceID, MCI_BUFFER,
                            MCI_WAIT | MCI_DEALLOCATE_MEMORY,
                            (PVOID)&dev->BufferParms, 0);

        /* Close device the mixer device
         */
        m_pfnmciSendCommand(dev->usDeviceID, MCI_CLOSE, MCI_WAIT,
                            (PVOID)&GenericParms, 0);
    }

    FLUID_FREE(dev);
    return FLUID_OK;
}
Ejemplo n.º 14
0
fluid_timer_t*
new_fluid_timer (int msec, fluid_timer_callback_t callback, void* data,
                 int new_thread, int auto_destroy, int high_priority)
{
  fluid_timer_t *timer;

  timer = FLUID_NEW (fluid_timer_t);

  if (timer == NULL)
  {
    FLUID_LOG (FLUID_ERR, "Out of memory");
    return NULL;
  }

  timer->msec = msec;
  timer->callback = callback;
  timer->data = data;
  timer->cont = TRUE ;
  timer->thread = NULL;
  timer->auto_destroy = auto_destroy;

  if (new_thread)
  {
    timer->thread = new_fluid_thread ("timer", fluid_timer_run, timer, high_priority
                                      ? FLUID_SYS_TIMER_HIGH_PRIO_LEVEL : 0, FALSE);
    if (!timer->thread)
    {
      FLUID_FREE (timer);
      return NULL;
    }
  }
  else fluid_timer_run (timer);  /* Run directly, instead of as a separate thread */

  return timer;
}
Ejemplo n.º 15
0
void
fluid_timer_run (void *data)
{
  fluid_timer_t *timer;
  int count = 0;
  int cont;
  long start;
  long delay;

  timer = (fluid_timer_t *)data;

  /* keep track of the start time for absolute positioning */
  start = fluid_curtime ();

  while (timer->cont)
  {
    cont = (*timer->callback)(timer->data, fluid_curtime() - start);

    count++;
    if (!cont) break;

    /* to avoid incremental time errors, calculate the delay between
       two callbacks bringing in the "absolute" time (count *
       timer->msec) */
    delay = (count * timer->msec) - (fluid_curtime() - start);
    if (delay > 0) fluid_usleep (delay * 1000);
  }

  FLUID_LOG (FLUID_DBG, "Timer thread finished");

  if (timer->auto_destroy)
    FLUID_FREE (timer);

  return;
}
Ejemplo n.º 16
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 */
}
Ejemplo n.º 17
0
static fluid_set_setting_t*
new_fluid_set_setting(void)
{
  fluid_set_setting_t* setting;

  setting = FLUID_NEW(fluid_set_setting_t);

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

  setting->node.type = FLUID_SET_TYPE;
  setting->hashtable = new_fluid_hashtable_full(fluid_str_hash, fluid_str_equal,
                                                fluid_settings_key_destroy_func,
                                                fluid_settings_value_destroy_func);
  if (!setting->hashtable)
  {
    FLUID_FREE (setting);
    return NULL;
  }

  return setting;
}
Ejemplo n.º 18
0
/*
 * delete_fluid_channel
 */
int
delete_fluid_channel(fluid_channel_t* chan)
{
  if (chan->preset) delete_fluid_preset (chan->preset);
  FLUID_FREE(chan);
  return FLUID_OK;
}
Ejemplo n.º 19
0
/**
 * Set a setting name, value and type, replacing it if already exists
 *
 * @param settings a settings object
 * @param name Settings name
 * @param value Node instance to assign (used directly)
 * @return 1 if the value has been set, zero otherwise
 */
static int
fluid_settings_set(fluid_settings_t* settings, const char *name, void* value)
{
  fluid_hashtable_t* table = settings;
  fluid_setting_node_t *node;
  char* tokens[MAX_SETTINGS_TOKENS];
  char buf[MAX_SETTINGS_LABEL+1];
  int n, num;
  char *dupname;

  num = fluid_settings_tokenize (name, buf, tokens) - 1;

  for (n = 0; n < num; n++) {

    node = fluid_hashtable_lookup(table, tokens[n]);

    if (node) {

      if (node->type == FLUID_SET_TYPE) {
	table = ((fluid_set_setting_t *)node)->hashtable;
      } else {
	/* path ends prematurely */
	FLUID_LOG(FLUID_WARN, "'%s' is not a node", name[n]);
	return 0;
      }

    } else {
      /* create a new node */
      fluid_set_setting_t* setnode;

      dupname = FLUID_STRDUP (tokens[n]);
      setnode = new_fluid_set_setting ();

      if (!dupname || !setnode)
      {
        if (dupname) FLUID_FREE (dupname);
        else FLUID_LOG(FLUID_ERR, "Out of memory");

        if (setnode) delete_fluid_set_setting (setnode);

        return 0;
      }

      fluid_hashtable_insert(table, dupname, setnode);
      table = setnode->hashtable;
    }
  }

  dupname = FLUID_STRDUP (tokens[num]);

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

  fluid_hashtable_insert(table, dupname, value);

  return 1;
}
Ejemplo n.º 20
0
void
delete_fluid_sndio_midi_driver(fluid_midi_driver_t *addr)
{
  int err;
  fluid_sndio_midi_driver_t *dev = (fluid_sndio_midi_driver_t *)addr;

  if (dev == NULL) {
    return;
  }
  dev->status = FLUID_MIDI_DONE;

  /* cancel the thread and wait for it before cleaning up */
  if (dev->thread) {
    err = pthread_cancel(dev->thread);
    if (err) {
      FLUID_LOG(FLUID_ERR, "Failed to cancel the midi thread");
      return;
    }
    if (pthread_join(dev->thread, NULL)) {
      FLUID_LOG(FLUID_ERR, "Failed to join the midi thread");
      return;
    }
  }
  if (dev->hdl != NULL) {
    mio_close(dev->hdl);
  }
  if (dev->parser != NULL) {
    delete_fluid_midi_parser(dev->parser);
  }
  FLUID_FREE(dev);
  return;
}
Ejemplo n.º 21
0
/**
 * Add a rule to a MIDI router.
 * @param router MIDI router
 * @param rule Rule to add (used directly and should not be accessed again following a
 *   successful call to this function).
 * @param type The type of rule to add (#fluid_midi_router_rule_type)
 * @return #FLUID_OK on success, #FLUID_FAILED otherwise (invalid rule for example)
 * @since 1.1.0
 */
int
fluid_midi_router_add_rule (fluid_midi_router_t *router, fluid_midi_router_rule_t *rule,
                            int type)
{
  fluid_midi_router_rule_t *free_rules, *next_rule;

  fluid_return_val_if_fail (router != NULL, FLUID_FAILED);
  fluid_return_val_if_fail (rule != NULL, FLUID_FAILED);
  fluid_return_val_if_fail (type >= 0 && type < FLUID_MIDI_ROUTER_RULE_COUNT, FLUID_FAILED);


  fluid_mutex_lock (router->rules_mutex);       /* ++ lock */

  /* Take over free rules list, if any (to free outside of lock) */
  free_rules = router->free_rules;
  router->free_rules = NULL;

  rule->next = router->rules[type];
  router->rules[type] = rule;

  fluid_mutex_unlock (router->rules_mutex);     /* -- unlock */


  /* Free any deactivated rules which were waiting for events and are now done */

  for (; free_rules; free_rules = next_rule)
  {
    next_rule = free_rules->next;
    FLUID_FREE (free_rules);
  }

  return FLUID_OK;
}
Ejemplo n.º 22
0
/**
 * Register a sequencer client.
 * @param seq Sequencer object
 * @param name Name of sequencer client
 * @param callback Sequencer client callback or NULL for a source client.
 * @param data User data to pass to the \a callback
 * @return Unique sequencer ID or #FLUID_FAILED on error
 *
 * Clients can be sources or destinations of events.  Sources don't need to
 * register a callback.
 */
short
fluid_sequencer_register_client (fluid_sequencer_t* seq, const char *name,
                                 fluid_event_callback_t callback, void* data)
{
	fluid_sequencer_client_t * client;
	char * nameCopy;

	client = FLUID_NEW(fluid_sequencer_client_t);
	if (client == NULL) {
		fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
		return FLUID_FAILED;
	}

	nameCopy = FLUID_STRDUP(name);
	if (nameCopy == NULL) {
		fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
		FLUID_FREE(client);
		return FLUID_FAILED;
	}

	seq->clientsID++;

	client->name = nameCopy;
	client->id = seq->clientsID;
	client->callback = callback;
	client->data = data;

	seq->clients = fluid_list_append(seq->clients, (void *)client);

	return (client->id);
}
Ejemplo n.º 23
0
static char*
fluid_file_read_full(fluid_file fp, size_t* length)
{
    size_t buflen;
    char* buffer;
    size_t n;
    /* Work out the length of the file in advance */
    if (FLUID_FSEEK(fp, 0, SEEK_END) != 0)
    {
        FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
        return NULL;
    }
    buflen = ftell(fp);
    if (FLUID_FSEEK(fp, 0, SEEK_SET) != 0)
    {
        FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
        return NULL;
    }
    FLUID_LOG(FLUID_DBG, "File load: Allocating %d bytes", buflen);
    buffer = FLUID_MALLOC(buflen);
    if (buffer == NULL) {
        FLUID_LOG(FLUID_PANIC, "Out of memory");
        return NULL;
    }
    n = FLUID_FREAD(buffer, 1, buflen, fp);
    if (n != buflen) {
        FLUID_LOG(FLUID_ERR, "Only read %d bytes; expected %d", n,
                  buflen);
        FLUID_FREE(buffer);
        return NULL;
    };
    *length = n;
    return buffer;
}
Ejemplo n.º 24
0
/**
 * Return a new MIDI file handle for parsing an already-loaded MIDI file.
 * @internal
 * @param buffer Pointer to full contents of MIDI file (borrows the pointer).
 *  The caller must not free buffer until after the fluid_midi_file is deleted.
 * @param length Size of the buffer in bytes.
 * @return New MIDI file handle or NULL on error.
 */
fluid_midi_file *
new_fluid_midi_file(const char* buffer, size_t length)
{
    fluid_midi_file *mf;

    mf = FLUID_NEW(fluid_midi_file);
    if (mf == NULL) {
        FLUID_LOG(FLUID_ERR, "Out of memory");
        return NULL;
    }
    FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));

    mf->c = -1;
    mf->running_status = -1;

    mf->buffer = buffer;
    mf->buf_len = length;
    mf->buf_pos = 0;
    mf->eof = FALSE;

    if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
        FLUID_FREE(mf);
        return NULL;
    }
    return mf;
}
Ejemplo n.º 25
0
/**
 * Delete MIDI event structure.
 * @param evt MIDI event structure
 * @return Always returns #FLUID_OK
 */
int
delete_fluid_midi_event(fluid_midi_event_t *evt)
{
    fluid_midi_event_t *temp;

    while (evt) {
        temp = evt->next;

        /* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
        if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2)
            FLUID_FREE (evt->paramptr);

        FLUID_FREE(evt);
        evt = temp;
    }
    return FLUID_OK;
}
Ejemplo n.º 26
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);
}
Ejemplo n.º 27
0
void 
delete_fluid_rvoice_eventhandler(fluid_rvoice_eventhandler_t* handler)
{
  if (handler == NULL) return;
  delete_fluid_rvoice_mixer(handler->mixer);
  delete_fluid_ringbuffer(handler->queue);
  delete_fluid_ringbuffer(handler->finished_voices);
  FLUID_FREE(handler);
}
Ejemplo n.º 28
0
static void
delete_fluid_set_setting(fluid_set_setting_t* setting)
{
  if (setting)
  {
    delete_fluid_hashtable(setting->hashtable);
    FLUID_FREE(setting);
  }
}
Ejemplo n.º 29
0
/**
 * Add a MIDI file to a player queue.
 * @param player MIDI player instance
 * @param midifile File name of the MIDI file to add
 * @return #FLUID_OK or #FLUID_FAILED
 */
int
fluid_player_add(fluid_player_t *player, const char *midifile)
{
    fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item));
    char* f = FLUID_STRDUP(midifile);
    if (!pi || !f) {
        FLUID_FREE(pi);
        FLUID_FREE(f);
        FLUID_LOG(FLUID_PANIC, "Out of memory");
        return FLUID_FAILED;
    }

    pi->filename = f;
    pi->buffer = NULL;
    pi->buffer_len = 0;
    player->playlist = fluid_list_append(player->playlist, pi);
    return FLUID_OK;
}
Ejemplo n.º 30
0
/**
 * Delete a MIDI file handle.
 * @internal
 * @param mf MIDI file handle to close and free.
 */
void
delete_fluid_midi_file (fluid_midi_file *mf)
{
    if (mf == NULL) {
        return;
    }
    FLUID_FREE(mf);
    return;
}