Пример #1
0
static void *
assoc_maintenance_thread(void *arg)
{
    uint32_t i, hv;
    struct item_slh *old_bucket, *new_bucket;
    struct item *it, *next;

    while (run_maintenance_thread) {
        /*
         * Lock the cache, and bulk move multiple buckets to the new
         * hash table
         */
        pthread_mutex_lock(&cache_lock);

        for (i = 0; i < nhash_move_size && expanding == 1; i++) {

            old_bucket = &old_hashtable[expand_bucket];

            SLIST_FOREACH_SAFE(it, old_bucket, h_sle, next) {
                hv = hash(item_key(it), it->nkey, 0);
                new_bucket = &primary_hashtable[hv & HASHMASK(hash_power)];
                SLIST_REMOVE(old_bucket, it, item, h_sle);
                SLIST_INSERT_HEAD(new_bucket, it, h_sle);
            }

            expand_bucket++;
            if (expand_bucket == HASHSIZE(hash_power - 1)) {
                expanding = 0;
                mc_free(old_hashtable);
                nbyte_old = 0;
            }
        }

        if (expanding == 0) {
            /* we are done expanding, just wait for the next invocation */
            pthread_cond_wait(&maintenance_cond, &cache_lock);
        }

        pthread_mutex_unlock(&cache_lock);
    }
Пример #2
0
static void library_view_process_lyric(char* lyric, void* data)
{
  
  struct lyric_cb* cb = (struct lyric_cb*) data;
  char* t_id = cb->track_id;
  library_view_t* view = cb->view;
  mc_free(cb);
  
  if (view->current_lyric_track_id != NULL) {
    mc_free(view->current_lyric_track_id);
  }
  view->current_lyric_track_id = t_id;
  
  track_t* t = library_get(view->library, t_id);
  if (t != NULL) {
    if (strcmp(lyric, "") != 0) {
      track_set_lyric(t, lyric);
    }
    
    char *artist = text_to_html(track_get_artist(t));
    char *title = text_to_html(track_get_title(t));
  
    char* s = (char*) mc_malloc(strlen(artist)+sizeof(", ")+strlen(title)+200);
    sprintf(s,"<span size=\"x-small\"><i><b>%s\n%s</b></i></span>", artist, title);
    gtk_label_set_markup(view->lbl_lyric_track,s);
    mc_free(s);
    
    mc_free(title);
    mc_free(artist);
    
    char* html = lyric_text_to_html(lyric);
    write_lyric(t, lyric, el_false); // write but don't overwrite
    webkit_web_view_load_string(view->lyric_view, html, NULL, NULL, "");
    mc_free(html);
  } else {
    char* html = "<html><head></head><body></body></html>";
    gtk_label_set_markup(view->lbl_lyric_track, "");
    webkit_web_view_load_string(view->lyric_view, html, NULL, NULL, "");
  }
  
  mc_free(lyric);
}
Пример #3
0
int cwdb_shutdown(void) {

#ifdef HAVE_MEMCACHE
    if ( memcached_data.mc ) {
        cw_log(LOG_DEBUG,"Database shutting down.\n");
        database_flush_cache();
        mc_free(memcached_data.mc);
        memcached_data.mc = NULL;
        memcached_data.active = 0;
    }
    if ( db_server_port ) {
        free(db_server_port);
        db_server_port = NULL;
    }
    if ( db_server_host ) {
        free(db_server_host);
        db_server_host = NULL;
    }
#endif

    return 0;
}
Пример #4
0
/*
 * Return an object back to the cache.
 *
 * The caller should return the object in an initialized state so that
 * the object may be returned in an expected state from cache_alloc.
 *
 * @param handle handle to the object cache to return the object to
 * @param ptr pointer to the object to return.
 */
void
cache_free(cache_t *cache, void *ptr)
{
    pthread_mutex_lock(&cache->mutex);

    if (cache->freecurr < cache->freetotal) {
        cache->ptr[cache->freecurr++] = ptr;
    } else {
        /* try to enlarge free connections array */
        size_t newtotal = cache->freetotal * 2;
        void **new_free = mc_realloc(cache->ptr, sizeof(char *) * newtotal);
        if (new_free != NULL) {
            cache->freetotal = newtotal;
            cache->ptr = new_free;
            cache->ptr[cache->freecurr++] = ptr;
        } else {
            mc_free(ptr);

        }
    }
    pthread_mutex_unlock(&cache->mutex);
}
Пример #5
0
static void sipmemcache_close(lua_State *L)
{
  struct sipmemcache *o;

  o = luaL_checkudata(L, 1, "siplua.memcache");
  if (!o->finalized && o->mc)
    {
      if (o->res)
	{
	  pkg_free(o->res);
	  o->res = NULL;
	}
      if (o->req)
	{
	  mc_req_free(o->req);
	  o->req = NULL;
	}
      mc_free(o->mc);
      o->mc = NULL;
      o->finalized = 1;
    }
}
Пример #6
0
void library_view_search_cover_art(GtkMenuItem* item, GObject* lview)
{
  library_view_t* view = (library_view_t*) g_object_get_data(lview, "library_view_t");

  GtkTreeSelection* sel = gtk_tree_view_get_selection(view->tview);
  GtkTreeModel* model;
  GtkTreeIter iter;

  if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
    int row = gtk_list_model_iter_to_row(GTK_LIST_MODEL(model), iter);
    track_t* track = playlist_model_get_track(view->playlist_model, row);

    char s[10240];
    strcpy(s, "https://www.google.nl/search?tbm=isch&q=%s");
    char url[20480];
    char query[10240];
  
    sprintf(query,"%s+%s",track_get_artist(track), track_get_album_title(track));
    char* q = to_http_get_query(query);
  
    sprintf(url, s, q);
    open_url(GTK_WIDGET(item), url);
    
    mc_free(q);
  } else {
    GtkMessageDialog* dialog = GTK_MESSAGE_DIALOG(
                                gtk_message_dialog_new(btb_main_window(view->btb),
                                                       GTK_DIALOG_DESTROY_WITH_PARENT,
                                                       GTK_MESSAGE_ERROR,
                                                       GTK_BUTTONS_CLOSE,
                                                       _("Please select a track to set the cover art for")
                                                       )
                                );
    gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy (GTK_WIDGET(dialog));        
  }
  
}
Пример #7
0
static char *myunquote(const char *s, const char *e)
{
  char *r = trim(s);
  char *p = &r[strlen(e)];
  while (isspace(p[0]) && p[0] != '\0') {
    p++;
  }
  if (p[0] == '\0') {
    return mystrdup("");
  } else {
    if (p[0] == '"') {
      p += 1;
    }
    if (p[strlen(p) - 1] == '"') {
      p[strlen(p) - 1] = '\0';
    }
    char *k = mystrdup(p);
    trim_replace(&k);
    mc_free(r);
    log_debug2("k=%s", k);
    return k;
  }
}
Пример #8
0
// same as pop_udr_stack except calls mc_free if PACMAN tag
//
void zap_udr_stack(mword *stack_ptr){ // zap_udr_stack#

    mword *free_ptr = (mword*)icar(stack_ptr);

    mword *tag = (mword*)icar(icdr(icar(icar(stack_ptr))));
    mword *temp = (mword*)icar(icar(icar(stack_ptr)));

    (mword*)*stack_ptr = _pop((mword*)icar(stack_ptr));

    //_dump(stack_ptr);

//    trace;
//    _mem(temp);
//    printf("\n");

    if(is_tptr(tag) && tageq(tag,BABEL_TAG_PACMAN,TAG_SIZE)){
        //printf("MATCH\n");
        mc_free(temp);
    }

    free_lumbar(free_ptr);

}
Пример #9
0
void read_in_sizes(const char *from_file) {

  FILE *f = fopen(from_file, "rt");
  if (f==NULL) {
    return;
  }

  char *line = (char *) mc_malloc(10240*sizeof(char));
  if (fgets(line, 10240, f) != NULL) {
    char *ln = trim(line);
    if (strcmp(ln, VFILESIZE_FILE_TYPE) == 0) {
      if (fgets(line, 10240, f) != NULL) {
        char *ln1 = trim(line);
        if (strcmp(ln1, VFILESIZE_FILE_VERSION) == 0) {
          while (fgets(line, 10240, f) != NULL) {
            char *ln2 = trim(line);
            char *vfile = mc_strdup( ln2 );
            fgets(line, 10240, f);
            char *ln3 = trim( line );
            size_t size = (size_t) strtoul(ln3, NULL, 10);
            fgets(line, 10240, f);
            char *ln4 = trim (line);
            time_t mtime = (time_t) strtoul(ln4, NULL, 10);
            put_size( vfile, size, mtime );
            mc_free( vfile);
            mc_free( ln4 );
            mc_free( ln3 );
            mc_free( ln2 );
          }
        }
        mc_free( ln1 );
      }
    }
    mc_free( ln );
  }
  mc_free(line);
  fclose(f);
}
Пример #10
0
static int mp3splt(segmenter_t * S)
{
  char *ext = getExt(S->segment.filename);

  //log_debug("mp3splt_split: entered");

  mc_free(S->memory_block);
  S->size = -1;
  S->memory_block = NULL;
#ifndef SEGMENT_USING_FILE
  FILE *f = open_memstream((char **)&S->memory_block, &S->size);
#endif

  int begin_offset_in_hs = S->segment.begin_offset_in_ms / 10;
  int end_offset_in_hs = -1;
  if (S->segment.end_offset_in_ms >= 0) {
    end_offset_in_hs = S->segment.end_offset_in_ms / 10;
  }
  // Creating state
  splt_state *state = mp3splt_new_state(NULL);
  //log_debug("new state");
  mp3splt_find_plugins(state);
  //log_debug("plugins found");

  // Set split path and custom name
  mp3splt_set_path_of_split(state, "/tmp");
  //log_debug("split path set");
  mp3splt_set_int_option(state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_CUSTOM);
  //log_debug("custom split set");

  // Set filename to split and pretend mode, for memory based splitting
  mp3splt_set_filename_to_split(state, S->segment.filename);
  //log_debug("filename to split set");
#ifndef SEGMENT_USING_FILE
  mp3splt_set_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_TRUE);
  mp3splt_set_pretend_to_split_write_function(state, mp3splt_writer, (void *)f);
  //log_debug("pretend split and write function set");
#endif

  // Create splitpoints
  splt_point *point = mp3splt_point_new(begin_offset_in_hs, NULL);
  mp3splt_point_set_type(point, SPLT_SPLITPOINT);
#ifdef SEGMENT_USING_FILE
  char buf[20];
  sprintf(buf, "mp3cue%09d", ++splitnr);
  mp3splt_point_set_name(point, buf);
#endif
  mp3splt_append_splitpoint(state, point);

  splt_point *skip = mp3splt_point_new(end_offset_in_hs, NULL);
  mp3splt_point_set_type(skip, SPLT_SKIPPOINT);
  mp3splt_append_splitpoint(state, skip);
  //log_debug("split points set");

  // Append cuesheet tags and merge with existing
  {
    splt_tags *tags = mp3splt_tags_new(NULL);

    char *title = S->segment.title;
    char *artist = S->segment.artist;
    char *album = S->segment.album;
    char *performer = S->segment.album_artist;
    char year[20];
    sprintf(year, "%d", S->segment.year);
    char *comment = S->segment.comment;
    char *genre = S->segment.genre;
    char track[20];
    sprintf(track, "%d", S->segment.track);

    mp3splt_read_original_tags(state);
    //log_debug("original tags read");

    mp3splt_tags_set(tags, SPLT_TAGS_ORIGINAL, "true", NULL);
    //log_debug("SPLT_TAGS_ORIGINAL set");
    mp3splt_tags_set(tags,
         SPLT_TAGS_TITLE, title,
         SPLT_TAGS_ARTIST, artist,
         SPLT_TAGS_ALBUM, album,
         SPLT_TAGS_PERFORMER, performer,
         SPLT_TAGS_YEAR, year,
         SPLT_TAGS_COMMENT, comment, SPLT_TAGS_GENRE, genre, SPLT_TAGS_TRACK, track, NULL);
    //log_debug("tags set");
    mp3splt_append_tags(state, tags);
    //log_debug("tag appended");
  }

  // split the stuff
  int error = SPLT_OK;
  error = mp3splt_split(state);
  //log_debug("split done");
  mp3splt_free_state(state);
  //log_debug("state freeed");
  log_debug2("mp3splt_split: result=%d", error);

#ifndef SEGMENT_USING_FILE
  fclose(f);
  mc_take_control(S->memory_block, S->size);
  //log_debug("memory file closed");
#endif

  if (error == SPLT_OK_SPLIT || error == SPLT_OK_SPLIT_EOF) {
#ifdef SEGMENT_USING_FILE
    char fn[250];
    sprintf(fn, "/tmp/%s.%s", buf, ext);
    FILE *f = fopen(fn, "rb");
    FILE *g = open_memstream((char **)&S->memory_block, &S->size);
    int size;
    char fbuf[10240];
    while ((size = fread(fbuf, 1, 10240, f)) > 0) {
      fwrite(fbuf, size, 1, g);
    }
    fclose(f);
    fclose(g);
    unlink(fn);
#endif
    mc_free(ext);
    return SEGMENTER_OK;
  } else {
    mc_free(ext);
    return SEGMENTER_ERR_CREATE;
  }
}
Пример #11
0
void library_view_init(library_view_t* view)
{
  // library view.
  GObject* object = gtk_builder_get_object(view->builder,"view_library");
  g_object_set_data(object, "library_view_t", (gpointer) view);
  
  // playlists (initially not viewed)
  //GtkWidget* scw_playlists = GTK_WIDGET(gtk_builder_get_object(view->builder,"scw_playlists"));
  //gtk_widget_hide(scw_playlists);

  // library list
  GtkTreeView* tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_library"));
  view->tview = tview;
  GtkTreeViewColumn *col;
  GtkCellRenderer* renderer;
  
  renderer = gtk_cell_renderer_text_new();
  
  view->cols = (GtkTreeViewColumn**) mc_malloc(sizeof(GtkTreeViewColumn*) * PLAYLIST_MODEL_N_COLUMNS);
  playlist_column_enum e;
  for(e = PLAYLIST_MODEL_COL_NR; e < PLAYLIST_MODEL_N_COLUMNS; ++e) {
    col = gtk_tree_view_column_new_with_attributes(i18n_column_name(e), renderer, "text", e, NULL);
    gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
    char path [500];
    sprintf(path, "library.column.%s.width", column_id(e));
    int width = el_config_get_int(btb_config(view->btb), path, 100);
    if (width < 10) { width = 100; }
    g_object_set_data(G_OBJECT(col), "column_id", (gpointer) column_id(e));
    gtk_tree_view_column_set_fixed_width(col, width);
    gtk_tree_view_column_set_reorderable(col, TRUE);
    gtk_tree_view_column_set_resizable(col, TRUE);
    gtk_tree_view_column_set_clickable(col, TRUE);
    g_signal_connect(col, "clicked", (GCallback) library_view_library_col_sort, view);
    g_signal_connect (col, "notify::width", G_CALLBACK (library_view_col_width_set), view);
    view->cols[e] = col;
    g_object_ref(view->cols[e]);
    gtk_tree_view_append_column(tview, col);
  }
  
  gtk_tree_view_set_model(tview, GTK_TREE_MODEL(playlist_model_gtk_model(view->playlist_model)));
  
  // Aspect lists
  int width;
  
  // Genres
  tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_genre_aspect"));
  col = gtk_tree_view_column_new_with_attributes(_("Genre"), renderer, "text", 0, NULL);
  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
  //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200);
  //gtk_tree_view_column_set_fixed_width(col, width);
  gtk_tree_view_append_column(tview, col);
  gtk_tree_view_set_model(tview, string_model_gtk_model(view->genre_model));
  
  // Artists
  tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_artist_aspect"));
  col = gtk_tree_view_column_new_with_attributes(_("Artists"), renderer, "text", 0, NULL);
  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
  //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200);
  //gtk_tree_view_column_set_fixed_width(col, width);
  gtk_tree_view_append_column(tview, col);
  gtk_tree_view_set_model(tview, string_model_gtk_model(view->artist_model));
  
  // Albums
  tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_album_aspect"));
  col = gtk_tree_view_column_new_with_attributes(_("Artists"), renderer, "text", 0, NULL);
  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
  //width = el_config_get_int(btb_config(view->btb), "library.aspects.column_width", 200);
  //gtk_tree_view_column_set_fixed_width(col, width);
  gtk_tree_view_append_column(tview, col);
  gtk_tree_view_set_model(tview, string_model_gtk_model(view->album_model));
  
  // Activate genres
  library_view_aspect_page(view, GENRE_ASPECT);
  GtkToggleToolButton* g_btn = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(view->builder, "tbtn_genres"));
  gtk_toggle_tool_button_set_active(g_btn, TRUE);
  
  // playback scale, song info
  GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback"));
  gtk_range_set_range(GTK_RANGE(sc_playback), 0.0, 100.0);
  { 
    char ss[300];
    sprintf(ss,"<span size=\"x-small\"><i><b> </b></i></span>");
    GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info"));
    gtk_label_set_markup(lbl, ss);
  }
  
  // Set logo
  {
    char *path = backtobasics_logo(view->btb); 
    file_info_t* info = file_info_new(path);
    mc_free(path);
    if (file_info_is_file(info)) {
      GError *err = NULL;
      GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info),
                                                        view->img_w, view->img_h,
                                                        TRUE,
                                                        &err
                                                        );
      GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art"));
      gtk_widget_set_size_request(GTK_WIDGET(img), view->img_w, view->img_h);
      if (pb != NULL) {
        gtk_image_set_from_pixbuf(img, pb);
        g_object_unref(pb);
      } else {
        log_error3("error loading image art: %d, %s", err->code, err->message);
        //g_free(err);
      }
    }
    file_info_destroy(info);
  }
  
  // Playlists
  tview = GTK_TREE_VIEW(gtk_builder_get_object(view->builder, "tv_playlists"));
  col = gtk_tree_view_column_new_with_attributes(_("Playlist"), renderer, "text", 0, NULL);
  gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED);
  width = el_config_get_int(btb_config(view->btb), "library.playlists.column_width", 200);
  gtk_tree_view_column_set_fixed_width(col, width);
  gtk_tree_view_append_column(tview, col);
  
  gtk_tree_view_set_model(tview, playlists_model_gtk_model(view->playlists_model));
  
  // Lyric view
  view->lyric_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
  view->lbl_lyric_track = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_lyric_track"));
  GtkScrolledWindow* scw_lyric = GTK_SCROLLED_WINDOW(gtk_builder_get_object(view->builder, "scw_lyric"));
  gtk_container_add(GTK_CONTAINER(scw_lyric), GTK_WIDGET(view->lyric_view));
  
  // visibility of columns
  {
    const char* names[] = {
      "chk_col_nr", "chk_col_title", "chk_col_artist", "chk_col_composer",
      "chk_col_piece", "chk_col_album", "chk_col_albumartist", "chk_col_genre",
      "chk_col_year", "chk_col_length", NULL
    };
    
    const playlist_column_enum es[] = {
      PLAYLIST_MODEL_COL_NR, PLAYLIST_MODEL_COL_TITLE, PLAYLIST_MODEL_COL_ARTIST,
      PLAYLIST_MODEL_COL_COMPOSER, PLAYLIST_MODEL_COL_PIECE, 
      PLAYLIST_MODEL_COL_ALBUM_TITLE, PLAYLIST_MODEL_COL_ALBUM_ARTIST,
      PLAYLIST_MODEL_COL_GENRE, PLAYLIST_MODEL_COL_YEAR, PLAYLIST_MODEL_COL_LENGTH,
      PLAYLIST_MODEL_N_COLUMNS
    };
    
    int i;
    for(i = 0;names[i] != NULL; ++i) {
      GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(view->builder, names[i]));
      gtk_widget_set_name(GTK_WIDGET(item), names[i]);
      char cfgitem[100];
      sprintf(cfgitem, "library.cols.%s", names[i]);
      int yes = el_config_get_int(btb_config(view->btb), cfgitem, 1);
      gtk_check_menu_item_set_active(item, yes);
      gtk_tree_view_column_set_visible(view->cols[es[i]], yes);
    }
  }
  
  // Start timeout every 250 ms
  g_timeout_add(250, (GSourceFunc) library_view_update_info, view); 
}
Пример #12
0
int main(char *argv[],int argc) {
  mc_init();
  el_bool stop = el_false;
  
  hre_t re_load = hre_compile("^load(&play)?\\s+(.*)$","i");
  hre_t re_play = hre_compile("^play$","i");
  hre_t re_pause = hre_compile("^pause$","i");
  hre_t re_next = hre_compile("^next$","i");
  hre_t re_previous = hre_compile("^prev(ious)?$","i");
  hre_t re_track = hre_compile("^track\\s+([0-9]+)$","i");
  hre_t re_quhit = hre_compile("^quit$","i");
  hre_t re_seek = hre_compile("^seek\\s([0-9]+([.][0-9]+)?)$","i");
  hre_t re_quit = hre_compile("^quit$","i");
  hre_t re_repeat = hre_compile("^repeat\\s+(off|list|track)$","i");
  hre_t re_again = hre_compile("^again$","i");
  hre_t re_scan = hre_compile("^scan\\s+(.*)$","i");
  
  file_info_t *history_file = mc_take_over(file_info_new_home(".btb_playlist"));
  printf("history file: %s\n", file_info_absolute_path(history_file));
  printf("history file: %s\n", file_info_path(history_file));
  if (file_info_exists(history_file)) {
    read_history(file_info_absolute_path(history_file));
  }
  
  i18n_set_language("nl");
  printf(_("Starting btb_playlist\n"));

  playlist_player_t *player = playlist_player_new();

  while (!stop) {
    char* line = readln(">", player);
    hre_trim(line);
    if (hre_has_match(re_quit, line)) {
      stop = el_true;
    } else if (hre_has_match(re_load, line)) {
      hre_matches m = hre_match(re_load, line);
      hre_match_t *mplay = hre_matches_get(m, 1);
      hre_match_t *match = hre_matches_get(m, 2);
      char* file = mc_strdup(hre_match_str(match));
      char* play = mc_strdup(hre_match_str(mplay));
      hre_matches_destroy(m);
      printf("loading '%s', '%s'\n", file, play);
      file_info_t *info = file_info_new(file);
      if (file_info_exists(info)) {
        if (file_info_is_file(info)) {
          if (file_info_can_read(info)) {
            const char *mediafile = NULL;
            track_array array;
            if (strcasecmp(file_info_ext(info),"cue") == 0) {
              array = tracks_from_cue(file_info_absolute_path(info));
              track_t* t = track_array_get(array, 0);
            } else {
              array = tracks_from_media(file_info_absolute_path(info));
            }
            playlist_t* pl = playlist_new("playlist");
            int i;
            for(i=0; i < track_array_count(array); ++i) {
              playlist_append(pl, track_array_get(array, i));
            }
            playlist_player_set_playlist(player, pl);
            track_array_destroy(array);
          }
        }
      }
      file_info_destroy(info);      
      if (strcasecmp(play,"&play")==0) { playlist_player_play(player); }
      mc_free(file);
      mc_free(play);
    } else if (hre_has_match(re_play, line)) {
      playlist_player_play(player);
    } else if (hre_has_match(re_pause, line)) {
      playlist_player_pause(player);
    } else if (hre_has_match(re_seek, line)) {
      hre_matches m = hre_match(re_seek, line);
      hre_match_t* match = hre_matches_get(m, 1);
      char* position = mc_strdup(hre_match_str(match));
      hre_matches_destroy(m);
      double s = atof(position);
      int ms = s * 1000;
      mc_free(position);
      playlist_player_seek(player, ms); 
    } else if (hre_has_match(re_next, line)) {
      playlist_player_next(player);
    } else if (hre_has_match(re_previous, line)) {
      playlist_player_previous(player);
    } else if (hre_has_match(re_track, line)) {
      hre_matches m = hre_match(re_track, line);
      hre_match_t* match = hre_matches_get(m, 1);
      char* nr = mc_strdup(hre_match_str(match));
      hre_matches_destroy(m);
      int index = atoi(nr);
      mc_free(nr);
      printf("setting track %d\n",index);
      playlist_player_set_track(player, index);
    } else if (hre_has_match(re_repeat, line)) {
      hre_matches m = hre_match(re_repeat, line);
      hre_match_t* match = hre_matches_get(m, 1);
      if (strcasecmp(hre_match_str(match),"track") == 0) {
        playlist_player_set_repeat(player, PLP_TRACK_REPEAT);
      } else if (strcasecmp(hre_match_str(match),"list") == 0) {
        playlist_player_set_repeat(player, PLP_LIST_REPEAT);
      } else {
        playlist_player_set_repeat(player, PLP_NO_REPEAT);
      }
      hre_matches_destroy(m);
    } else if (hre_has_match(re_again, line)) {
      playlist_player_again(player);
    } else if (hre_has_match(re_scan, line)) {
      hre_matches m = hre_match(re_scan, line);
      hre_match_t* match = hre_matches_get(m, 1);
      printf("scanning %s\n", hre_match_str(match));
      library_t* library = library_new();
      printf("calling scan_library\n");
      //scan_library(library, hre_match_str(match), library_cb);
      printf("\n");
      printf("library: %d tracks\n", library_count(library));
      printf("done scanning, destroying library\n");
      library_destroy(library);
      printf("library destroyed\n");
      hre_matches_destroy(m);
      printf("matches destroyed\n");
    }
    
    mc_free(line);
  }

  playlist_player_destroy(player);
  
  printf("%d\n",write_history(file_info_absolute_path(history_file)));
  
  file_info_destroy(history_file);
  hre_destroy(re_load);
  hre_destroy(re_play);
  hre_destroy(re_pause);
  hre_destroy(re_quit);
  hre_destroy(re_seek);
  hre_destroy(re_track);
  hre_destroy(re_next);
  hre_destroy(re_previous);
  hre_destroy(re_again);
  hre_destroy(re_repeat);
  hre_destroy(re_scan);
  
  return 0;
}
Пример #13
0
static int
load_elf(const char *path, void **basep, struct mc_module **modp)
{
	struct mc_elf elf;
	unsigned int i;
	uint32_t psize = 0, sz;
	uint8_t *base = NULL;
	uint8_t *paddr = NULL, *adr;
	struct mc_module *mod = NULL;
	int err = -1;

	mc_log_debug("ELF: loading %s...\n", path);
	if (mc_elf_open(path, &elf) != 0) {
		mc_log_error("ELF: cannot open %s\n", path);
		return -1;
	}
	/* calculate the entire program size in VM */
	for (i = 0; i < NUM_EXT_SECTIONS; i++) {
		if (mc_elf_get_section_addr_and_size(&elf, ext_sections[i], &adr, &sz) != 0)
			continue;
		if (adr >= paddr) {
			paddr = adr;
			psize = (uint32_t)paddr + sz;
		}
	}
	mc_log_debug("ELF: allocating %d bytes...\n", (unsigned int)psize);
	if ((base = mc_malloc(psize)) == NULL)
		goto bail;
	/* load each section */
	for (i = 0; i < NUM_EXT_SECTIONS; i++) {
		if (mc_elf_load_section(&elf, ext_sections[i], base) != 0)
			mc_log_error("cannot load %s (%d)\n", ext_sections[i], err);
	}
#if 0
	/* adjust function(?) addresses */
	if (mc_elf_get_section_addr_and_size(&elf, ".got", &adr, &sz) == 0) {
		uint32_t *gadr = (uint32_t *)(adr + (uint32_t)base), *eadr = (uint32_t *)(adr + (uint32_t)base + sz);
		for (; gadr < eadr; gadr++) {
/*
			if (*gadr & 0xf0000000) {
				*gadr = (*gadr & ~0xf0000000) + (uint32_t)base;
				mc_log_debug("adjusted: 0x%lx\n", *gadr);
			}
*/
			*gadr += (uint32_t)base;
		}
	}
#endif
	/* relocate variables */
	if (mc_elf_set_position(&elf, ".rel.dyn") == 0) {
		struct elf_rel rel;
		while (mc_elf_read(&elf, &rel, sizeof(rel)) == 0) {
			switch (ELF32_R_TYPE(rel.info)) {
			case 0x17:	/* R_ARM_RELATIVE */
				*(uint32_t *)(rel.offset + (uint32_t)base) += (uint32_t)base;
				// mc_log_debug("RELOC (rel): %x: %x\n", rel.offset, *(uint32_t *)(rel.offset + (uint32_t)base));
				break;
			case 0x02: {	/* R_ARM_ABS32 */
				struct elf_sym sym;
				if (mc_elf_get(&elf, ".dynsym", &sym, sizeof(sym), ELF32_R_SYM(rel.info)) != 0) {
					mc_log_error("cannot read .dynsym %ld\n", ELF32_R_SYM(rel.info));
					goto bail;
				}
				*(uint32_t *)(rel.offset + (uint32_t)base) = sym.value + (uint32_t)base;
				// mc_log_debug("RELOC (abs): %x: %x\n", rel.offset, *(uint32_t *)(rel.offset + (uint32_t)base));
				break;
			}
			default:
				/* no-op */
				mc_log_error("RELOC unknown type: 0x%x\n", ELF32_R_TYPE(rel.info));
				break;
			}
		}
	}
	paddr = mc_elf_get_entry(&elf);
	// mc_log_debug("ELF: entry = 0x%lx, base = 0x%lx\n", (uint32_t)paddr, (uint32_t)base);
	paddr += (uint32_t)base;
	mod = (struct mc_module *)paddr;
	*mod->stubs = (const void **)ext_stubs;
	*mod->num_stubs = num_ext_stubs;
	*basep = base;
	*modp = mod;
	err = 0;

bail:
	mc_elf_close(&elf);
	if (err != 0 && base != NULL)
		mc_free(base);
	return err;
}
Пример #14
0
void
xs_i2c_write(xsMachine *the)
{
	wm_i2c *i2c = xsGetHostData(xsThis);
	int ac = xsToInteger(xsArgc);
	int reg;
	uint8_t *data;
	int datasize;
	uint8_t num;
	uint8_t *allocated = NULL;

	if (ac < 2)
		return;
#if I2C_SUPPORT_CONCURRENCY
	if (i2c->slave_addr != i2c_current_slave_addr)
		i2c_config(i2c);
#endif
	switch (xsTypeOf(xsArg(0))) {
	case xsNumberType:
	case xsIntegerType:
		reg = xsToInteger(xsArg(0));
		break;
	default:
		reg = -1;
		break;
	}
	switch (xsTypeOf(xsArg(1))) {
	case xsIntegerType:
	case xsNumberType:
		num = (uint8_t)xsToInteger(xsArg(1));
		data = &num;
		datasize = 1;
		break;
	case xsReferenceType:
		if (xsIsInstanceOf(xsArg(1), xsArrayPrototype)) {
			int i;
			xsVars(1);
			xsGet(xsVar(0), xsArg(1), xsID("length"));
			datasize = xsToInteger(xsVar(0));
			if ((allocated = mc_malloc(datasize)) == NULL)
				mc_xs_throw(the, "no mem");
			for (i = 0; i < datasize; i++) {
				xsGet(xsVar(0), xsArg(1), (xsIndex)i);
				allocated[i] = (uint8_t)xsToInteger(xsVar(0));
			}
			data = allocated;
		}
		else {
			datasize = xsGetArrayBufferLength(xsArg(1));
			data = xsToArrayBuffer(xsArg(1));
		}
		break;
	default:
		mc_xs_throw(the, "args");
		return;	/* NOT REACHED */
	}
	if (ac > 2) {
		int n = xsToInteger(xsArg(2));
		if (datasize > n)
			datasize = n;
	}

	if (!i2c_wait_for_ack(i2c, i2c->txtout))
		mc_log_debug("I2C: write: no ack!\n");
	if (!i2c_write_bytes(i2c, reg, data, datasize))
		goto bail;
	(void)i2c_wait_tx_fifo(i2c);	/* send the stop sequence */

	if (allocated != NULL)
		mc_free(allocated);
	xsSetTrue(xsResult);
bail:
	return;
}
Пример #15
0
int
main(int argc, char *argv[]) {
  struct memcache *mc = NULL;
  u_int32_t num_tests = 0, valsize = 0;
  u_int32_t i;
  struct timeval t1, t2;
  const char *key;
  char *tests = NULL;
  char *val;
  u_int32_t keylen;
  double addtime, deltime;
  const char fmt[] = "%s\t%f\t%f\t%f\n";
  struct memcache_req *req;
  struct memcache_res *res;

  if (argc > 1)
    num_tests = strtol(argv[1], NULL, 10);

  if (num_tests == 0)
    num_tests = 10;

  if (argc > 2)
    valsize = strtol(argv[2], NULL, 10);

  if (argc > 3)
    tests = strdup(argv[3]);

  if (tests == NULL)
    tests = strdup("adgs");

  if (valsize == 0)
    valsize = 50;

  val = (char *)malloc(valsize + 1);
  memset(val, 69, valsize);
  val[valsize] = '\0';

  /* XXX I should add a min/max time value for each request */
  printf("Value size:\t%d\n", valsize);
  printf("Num tests:\t%d\n", num_tests);
  printf("Test\tOps per second\tTotal Time\tTime per Request\n");

  key = "bench_key";
  keylen = strlen(key);

  mc = mc_new();
  if (mc == NULL)
    err(EX_OSERR, "Unable to allocate a new memcache object");

  mc_err_filter_del(MCM_ERR_LVL_INFO);
  mc_err_filter_del(MCM_ERR_LVL_NOTICE);

  mc_server_add4(mc, "localhost:11211");

  /* Establish a connection */
  mc_set(mc, key, keylen, val, valsize, 0, 0);

  /* BEGIN set test, if specified */
  if (strchr(tests, (int)'s') != NULL) {
    if (gettimeofday(&t1, NULL) != 0)
      err(EX_OSERR, "gettimeofday(2)");

    for (i = 0; i < num_tests; i++) {
      mc_set(mc, key, keylen, val, valsize, 0, 0);
    }

    if (gettimeofday(&t2, NULL) != 0)
      err(EX_OSERR, "gettimeofday(2)");
    /* END set test */
    printf(fmt, "set", num_tests / tt(&t1, &t2), tt(&t1, &t2), tt(&t1, &t2) / num_tests);
  }


  if (strchr(tests, (int)'g') != NULL) {
    /* BEGIN get request */
    req = mc_req_new();
    res = mc_req_add(req, key, keylen);
    res->size = valsize;
    res->val = malloc(res->size);
    mc_res_free_on_delete(res, 1);

    if (gettimeofday(&t1, NULL) != 0)
      err(EX_OSERR, "gettimeofday(2)");

    for (i = 0; i < num_tests; i++) {
      mc_get(mc, req);
    }

    if (gettimeofday(&t2, NULL) != 0)
      err(EX_OSERR, "gettimeofday(2)");

    mc_req_free(req);
    /* END get test */
    printf(fmt, "get", num_tests / tt(&t1, &t2), tt(&t1, &t2), tt(&t1, &t2) / num_tests);
  }



  if (strchr(tests, 'a') != NULL || strchr(tests, 'd') != NULL) {
    /* Run the add/delete test */
    mc_delete(mc, key, keylen, 0);
    addtime = deltime = 0.0;
    for (i = 0; i < num_tests; i++) {
      /* BEGIN add test */
      if (strchr(tests, 'a') != NULL) {
	if (gettimeofday(&t1, NULL) != 0)
	  err(EX_OSERR, "gettimeofday(2)");

	mc_add(mc, key, keylen, val, valsize, 0, 0);

	if (gettimeofday(&t2, NULL) != 0)
	  err(EX_OSERR, "gettimeofday(2)");

	addtime += tt(&t1, &t2);
	/* END add test */
      }

      /* BEGIN delete test */
      if (strchr(tests, 'd') != NULL) {
	if (gettimeofday(&t1, NULL) != 0)
	  err(EX_OSERR, "gettimeofday(2)");

	mc_delete(mc, key, keylen, 0);

	if (gettimeofday(&t2, NULL) != 0)
	  err(EX_OSERR, "gettimeofday(2)");

	deltime += tt(&t1, &t2);
	/* END delete test */
      }
    }

    if (strchr(tests, 'a') != NULL)
      printf(fmt, "add",    num_tests / addtime, addtime, addtime / num_tests);

    if (strchr(tests, 'd') != NULL)
      printf(fmt, "delete", num_tests / deltime, deltime, deltime / num_tests);
  }


  free(tests);
  free(val);
  mc_free(mc);

  return EX_OK;
}
Пример #16
0
void vfile_size_destroy(hash_data_t d) {
  log_debug("destroying size hash elem");
  vfile_size_t *fs=(vfile_size_t *) d;
  mc_free(fs);
}
Пример #17
0
void free_lumbar(mword *stack_entry){

    mc_free((mword*)icdr(stack_entry));
    mc_free(stack_entry);

}
Пример #18
0
cue_t *cue_new(const char *file)
{
  cue_t *r = (cue_t *) mc_malloc(sizeof(cue_t));

  r->audio_file = NULL;
  r->album_title = NULL;
  r->album_performer = NULL;
  r->album_composer = NULL;
  r->genre = NULL;
  r->cuefile = mystrdup(file);
  r->count = 0;
  r->entries = NULL;
  r->_errno = 0;

  FILE *f = fopen(file, "rt");
  time_t _audio_mtime=0;

  if (f == NULL) {
    r->_errno = ENOFILECUE;
  } else {
    char *line;
    char *image = NULL;
    char *year = NULL;
    cue_entry_t *entry = NULL;
    int in_tracks = 0;
    while ((line = readline(f)) != NULL) {
      trim_replace(&line);
      if (strcmp(line, "") != 0) {
        if (!in_tracks) {
          if (eq(line, "performer")) {
            mc_free(r->album_performer);
            r->album_performer = unquote(line, "performer");
          } else if (eq(line, "title")) {
            mc_free(r->album_title);
            r->album_title = unquote(line, "title");
          } else if (eq(line, "file")) {
            mc_free(r->audio_file);
            char *fl = getFilePart(line);
            char *af = unquote(fl, "");
            if (strlen(af) > 0) {
              if (af[0] == '/') {
                r->audio_file = af;
              } else {
                char *cf = mc_strdup(r->cuefile);
                int ii;
                for (ii = strlen(cf) - 1; ii >= 0 && cf[ii] != '/'; ii--) ;
                if (ii >= 0) {
                  cf[ii] = '\0';
                  char *aaf = (char *)mc_malloc(strlen(cf) + strlen(af) + strlen("/") + 1);
                  sprintf(aaf, "%s/%s", cf, af);
                  r->audio_file = aaf;
                  mc_free(cf);
                  mc_free(af);
                } else {
                  r->audio_file = af;
                }
              }
            } else {
              r->audio_file = af;
            }
            // We have a full path audio file now.
            // get the mtime.
            {
              struct stat st;
              stat(r->audio_file,&st);
              _audio_mtime=st.st_mtime;
            }

            mc_free(fl);
          } else if (eq(line, "rem")) {
            if (eq(&line[3], "date")) {
              mc_free(year);
              year = unquote(&line[3], "date");
            } else if (eq(&line[3], "image")) {
              mc_free(image);
              image = unquote(&line[3], "image");
            } else if (eq(&line[3], "composer")) {
              mc_free(r->album_composer);
              r->album_performer = unquote(&line[3], "composer");
            } else if (eq(&line[3], "genre")) {
              mc_free(r->genre);
              r->genre = unquote(&line[3], "genre");
            }
          } else if (eq(line, "track")) {
            in_tracks = 1;
          }
        }

        if (in_tracks) {
          if (eq(line, "track")) {
            log_debug2("track: entry=%p", entry);
            if (entry != NULL) {
              addEntry(r, entry);
            }
            entry = cue_entry_new(r);
            entry->audio_mtime=_audio_mtime;
            entry->year = mystrdup(year);
            entry->performer = mystrdup(r->album_performer);
            entry->composer = mystrdup(r->album_composer);
            entry->piece = NULL;
            log_debug2("track: created new entry %p", entry);
          } else if (eq(line, "title")) {
            mc_free(entry->title);
            entry->title = unquote(line, "title");
          } else if (eq(line, "performer")) {
            mc_free(entry->performer);
            entry->performer = unquote(line, "performer");
          } else if (eq(line, "index")) {
            char *index = unquote(line, "index");
            entry->begin_offset_in_ms = calculateOffset(index);
            mc_free(index);
          } else if (eq(line, "rem")) {
            if (eq(&line[3], "composer")) {
              mc_free(entry->composer);
              entry->composer = unquote(&line[3], "composer");
            } else if (eq(&line[3], "piece")) {
              mc_free(entry->piece);
              entry->piece = unquote(&line[3], "piece");
            } else if (eq(&line[3], "year")) {
              mc_free(year);
              year = unquote(&line[3], "year");
              mc_free(entry->year);
              entry->year = mystrdup(year);
            }
          }
        }
      }
      mc_free(line);
    }
    if (entry != NULL) {
      addEntry(r, entry);
    }
    mc_free(year);
    mc_free(image);


    {
      int i, N;
      for (i = 0, N = r->count; i < N - 1; i++) {
        r->entries[i]->end_offset_in_ms = r->entries[i + 1]->begin_offset_in_ms;
        r->entries[i]->tracknr = i + 1;
      }
      r->entries[i]->tracknr = i + 1;
    }

    fclose(f);
  }

  return r;
}
Пример #19
0
void playlists_model_destroy(playlists_model_t* model) 
{
  gtk_list_model_destroy(model->model);
  mc_free(model);
}
Пример #20
0
static void mytrim_replace(char **line)
{
  char *rl = trim(*line);
  mc_free(*line);
  *line = rl;
}
Пример #21
0
static gboolean library_view_update_info(library_view_t* view)
{
  if (view->run_timeout) {
    
    // update play buttons
    playlist_player_t* player = backtobasics_player(view->btb);
    if (view->btn_play == NULL) {
      view->btn_play = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_play"));
    }
    if (view->btn_pause == NULL) {
      view->btn_pause = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_pause"));
    }
    GtkWidget* btn_play = view->btn_play;
    GtkWidget* btn_pause = view->btn_pause;
    if (!playlist_player_is_playing(player)) {
      if (!gtk_widget_get_visible(btn_play)) gtk_widget_show_all(btn_play);
      if (gtk_widget_get_visible(btn_pause)) gtk_widget_hide(btn_pause);
    } else if (playlist_player_is_playing(player)) {
      if (gtk_widget_get_visible(btn_play)) gtk_widget_hide(btn_play);
      if (!gtk_widget_get_visible(btn_pause)) gtk_widget_show_all(btn_pause);
    }
    
    // update slider and time
    long tr_tm = playlist_player_get_track_position_in_ms(player);
    track_t* track = playlist_player_get_track(player);
    int index = playlist_player_get_track_index(player);
    
    int a = tr_tm / 1000;
    int b = view->time_in_ms / 1000;
    
    if (a != b) {
      view->time_in_ms = tr_tm;
      int min = tr_tm / 1000 / 60;
      int sec = (tr_tm / 1000) % 60;
      { 
        char s[200]; 
        sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec);
        GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_time"));
        gtk_label_set_markup(lbl, s);
        
        // update presets
        reflect_presets(view->btb);
      }
      
      GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback"));
      double perc = 0.0;
      if (track != NULL) {
        int len_in_ms = track_get_length_in_ms(track);
        
        if (len_in_ms != view->len_in_ms) {
          view->len_in_ms = len_in_ms;
          int min = len_in_ms / 1000 / 60;
          int sec = (len_in_ms / 1000) % 60;
          {
            char s[200];
            sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec);
            GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_total"));
            gtk_label_set_markup(lbl, s);
          }
        }
        
        perc = (((double) tr_tm) / ((double) len_in_ms)) * 100.0;
        if (!view->sliding) {
          gtk_range_set_value(GTK_RANGE(sc_playback), perc);
        }
      }

      // update track info
      if (index != view->track_index || 
            (track != NULL && track_get_id(track) != view->track_id)) {
        log_debug3("updating track info, index = %d, %p", index, track);
        view->track_index = index;
        if (track != NULL) {
          
          // fetch lyric if possible
          if (strcmp(track_get_lyric(track),"") == 0) {
            struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb));
            cb->track_id = mc_strdup(track_get_id(track));
            cb->view = view;
            fetch_lyric(track, library_view_process_lyric, cb);
          } else {
            struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb));
            cb->track_id = mc_strdup(track_get_id(track));
            cb->view = view;
            library_view_process_lyric(mc_strdup(track_get_lyric(track)), cb);
          }
            
          // Print artist info
          view->track_id = track_get_id(track);
          log_debug2("artid = %s", track_get_artid(track));
          char s[200];
          char c = ',';
          char c1 = ',';
          char *artist = text_to_html(track_get_artist(track));
          char *title = text_to_html(track_get_title(track));
          char *piece = text_to_html(track_get_piece(track));
          
          if (strcmp(track_get_artist(track), "") == 0) { c = ' '; }
          if (strcmp(track_get_piece(track), "") == 0) { c1 = ' '; }
          snprintf(s, 125,
                   "%s%c %s%c %s", 
                   artist,
                   c,
                   piece,
                   c1,
                   title
                   );
          mc_free(artist);
          mc_free(title);
          mc_free(piece);
          char ss[400];
          log_debug2("s = %s", s);
          sprintf(ss,"<span size=\"x-small\"><i><b>%s</b></i></span>",s);
          GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info"));
          gtk_label_set_markup(lbl, ss);
          
          log_debug2("artid = %s", track_get_artid(track));
          file_info_t* info = file_info_new(track_get_artid(track));
          if (!file_info_is_file(info)) {
            file_info_destroy(info);
            char *path = backtobasics_logo(view->btb); 
            info = file_info_new(path);
            mc_free(path);
            //info = file_info_new(backtobasics_logo(view->btb));
          }
          
          if (file_info_is_file(info)) {
            GError *err = NULL;
            GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info),
                                                              view->img_w, view->img_h,
                                                              TRUE,
                                                              &err
                                                              );
            if (pb != NULL) {
              GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art"));
              gtk_image_set_from_pixbuf(img, pb);
              g_object_unref(pb);
            } else {
              log_error3("error loading image art: %d, %s", err->code, err->message);
              //g_free(err);
            }
          }
          file_info_destroy(info);
        }

        log_debug("track hash");

        
        // Select the track in the librarylist if the librarylist is still
        // the same
        if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) {
          GtkTreeView* tview = view->tview;
          GtkTreePath* path = gtk_tree_path_new();
          gtk_tree_path_append_index(path, index);
          gtk_tree_view_set_cursor(tview, path, NULL, FALSE);
          gtk_tree_path_free(path);
        } 
        log_debug("track hash 2");
        
      }

      //log_debug3("lib hash = %lld, pl hash = %lld", view->library_list_hash, playlist_player_get_hash(player));
      
      // TODO
      if (playlist_model_tracks_hash(view->playlist_model) ==  playlist_player_get_hash(player)) {
        //view->track_index = -1;
      } else {
        
        GtkTreeView* tview = view->tview;
        GtkTreeSelection* sel = gtk_tree_view_get_selection(tview);
        gtk_tree_selection_unselect_all(sel);
      }
      
    }
    
    // update repeat info
    playlist_player_repeat_t repeat = playlist_player_get_repeat(player);
    if (view->repeat != repeat) {
      log_debug3("repeat = %d, view repeat = %d", repeat, view->repeat);
      view->repeat = repeat;
      GtkWidget* r_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat"));
      GtkWidget* r1_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_one"));
      GtkWidget* rlist_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_all"));
      log_debug4("r = %p, r1 = %p, rall = %p", r_btn, r1_btn, rlist_btn);
      switch (repeat) {
        case PLP_NO_REPEAT: {
          gtk_widget_show_all(r_btn);
          gtk_widget_hide(rlist_btn);
          gtk_widget_hide(r1_btn);
        }
        break;
        case PLP_TRACK_REPEAT: {
          gtk_widget_hide(r_btn);
          gtk_widget_show_all(r1_btn);
          gtk_widget_hide(rlist_btn);
        }
        break;
        case PLP_LIST_REPEAT: {
          gtk_widget_hide(r1_btn);
          gtk_widget_show_all(rlist_btn);
          gtk_widget_hide(r_btn);
        }
        break;
      }
    }

    
    return TRUE;
  } else {
    return FALSE;
  }
}
Пример #22
0
void* player_thread(void* _mp3_info) 
{
  log_debug("player thread started");
  
  mp3_t* mp3_info = (mp3_t* ) _mp3_info;
  long current_position_in_ms = 0;
  long previous_position_in_ms = -1; 
  long guard_position_in_ms = -1;
  el_bool playing = el_false;
  pthread_t thread_id;
  int no_count = 0;
  
  post_event(mp3_info->client_notification, AUDIO_READY, current_position_in_ms);
 
  audio_event_t *event;
  event = audio_event_fifo_dequeue(mp3_info->player_control);
  while (event->state != INTERNAL_CMD_DESTROY) {
    
    if (event->state != INTERNAL_CMD_NONE) {
      log_debug4("event = %s, %ld, %s", audio_event_name(event->state), event->position_in_ms, mp3_info->file_or_url);
    }
    
    audio_state_t event_state = event->state;
    long event_position = event->position_in_ms;
    audio_event_destroy(event);
    
    switch (event_state) {
      case INTERNAL_CMD_LOAD_FILE: {
        playing = el_false;
        
        // Stop stream, if playing
        if (!mp3_info->is_file) {
          mp3_info->continue_streaming = el_false;
          psem_wait(mp3_info->stream_ready);
        }
        
        if (mp3_info->is_open) {
          mpg123_close(mp3_info->handle);
          aodev_close(mp3_info->ao_handle);
        }
        mpg123_open(mp3_info->handle, mp3_info->file_or_url);
        mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding);
        mp3_info->buffer_size = mpg123_outblock(mp3_info->handle);
        mc_free(mp3_info->buffer);
        mp3_info->buffer = mc_malloc(mp3_info->buffer_size * sizeof(char) );
        int bytes_per_sample = get_encsize(mp3_info->encoding);
        aodev_set_format(mp3_info->ao_handle, bytes_per_sample * 8, mp3_info->rate, mp3_info->channels);
        aodev_open(mp3_info->ao_handle);
        mp3_info->is_open = el_true;
        mp3_info->is_file = el_true;
        mp3_info->can_seek = el_true;
        current_position_in_ms = 0;
        guard_position_in_ms = -1; 
        {
          off_t l = mpg123_length(mp3_info->handle);
          if (l == MPG123_ERR) {
            mp3_info->length = -1; 
          } else {
            mp3_info->length = (l * 1000) / mp3_info->rate;
          }
          psem_post(mp3_info->length_set);
        }
      }
      break;
      case INTERNAL_CMD_LOAD_URL: {
        playing = el_false;
        log_debug2("loading url %s", mp3_info->file_or_url);
        // Wait for feeding streams to end
        if (!mp3_info->is_file) {
          mp3_info->continue_streaming = el_false;
          psem_wait(mp3_info->stream_ready);
        }
        mp3_info->is_file = el_false;
        log_debug("current stream ended");
        
        if (mp3_info->is_open) {
          mpg123_close(mp3_info->handle);
          aodev_close(mp3_info->ao_handle);
          mp3_info->is_open = el_false;
        }
        log_debug("aodev closed");
        
        mpg123_open_feed(mp3_info->handle);
        log_debug("feed opened");
        
        pthread_create(&thread_id, NULL, stream_thread, mp3_info);
        log_debug("stream thread started");
        
        mp3_info->is_open = el_true;
        mp3_info->can_seek = el_false;
        current_position_in_ms = 0;
        guard_position_in_ms = -1;
        mp3_info->length = 0;
        mp3_info->continue_streaming = el_true;
        
        psem_post(mp3_info->length_set);
      }
      break;
      case INTERNAL_CMD_SEEK: {
        off_t pos = mpg123_timeframe(mp3_info->handle, (event_position / 1000.0));
        mpg123_seek_frame(mp3_info->handle, pos, SEEK_SET);
      }
      break;
      case INTERNAL_CMD_PLAY: {
        playing = el_true;
      }
      break;
      case INTERNAL_CMD_PAUSE: {
        playing = el_false;
      }
      break;
      case INTERNAL_CMD_GUARD: {
        guard_position_in_ms = event_position;
      }
      break;
      case INTERNAL_CMD_SET_VOLUME: {
        double volume = ((double) event_position) / 1000.0;
        mpg123_volume(mp3_info->handle, volume);
      }
      case INTERNAL_CMD_NONE:
      break;
      default:
      break;
    }
    
    //log_debug3("guard = %d, playing = %d", guard_position_in_ms, playing);
    if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) {

      guard_position_in_ms = -1;
      post_event(mp3_info->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms);
      
    } else if (playing) {

      if (mp3_info->is_file) {  
        size_t bytes;
        int res = mpg123_read(mp3_info->handle, mp3_info->buffer, mp3_info->buffer_size, &bytes);
        if (res == MPG123_OK) {
          aodev_play_buffer(mp3_info->ao_handle, mp3_info->buffer, bytes);
          off_t frame = mpg123_tellframe(mp3_info->handle);
          double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0);
          //static int prt = 1;
          //if (prt) { printf("tpf=%.6lf\n",time_per_frame);prt=0; }
          current_position_in_ms = (long) (frame * time_per_frame);    // 1 frame is about 26 milliseconds
          if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms;
          if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
            post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms);
          }
          previous_position_in_ms = current_position_in_ms;
        } else if (res == MPG123_DONE) {
          post_event(mp3_info->client_notification, AUDIO_EOS, current_position_in_ms);
          playing = el_false;
        } else {
          post_event(mp3_info->client_notification, AUDIO_STATE_ERROR, current_position_in_ms);
          playing = el_false;
        }
      } else { // Stream playing
        
        if (mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) {
          el_bool go_on = el_true; 
          while (go_on && mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) {
            memblock_t* blk = mp3_stream_fifo_dequeue(mp3_info->stream_fifo);
            
            mpg123_feed(mp3_info->handle, (const unsigned char*) memblock_as_str(blk), memblock_size(blk));
            memblock_destroy(blk);
            
            size_t done;
            int err;
            unsigned char *audio;
            off_t frame_offset;
            
            do {
              err = mpg123_decode_frame(mp3_info->handle, &frame_offset, &audio, &done);
              switch(err) {
                case MPG123_NEW_FORMAT:
                  mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding);
                  if (aodev_is_open(mp3_info->ao_handle)) {
                    aodev_close(mp3_info->ao_handle);
                  }
                  aodev_set_format(mp3_info->ao_handle, get_encsize(mp3_info->encoding) * 8, mp3_info->rate, mp3_info->channels);
                  aodev_open(mp3_info->ao_handle);
                break;
                case MPG123_OK:
                  //log_debug2("playing buffer %d", done);
                  aodev_play_buffer(mp3_info->ao_handle, audio, done);
                  off_t frame = mpg123_tellframe(mp3_info->handle);
                  double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0);
                  current_position_in_ms = (long) (frame * time_per_frame);    // 1 frame is about 26 milliseconds
                  if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms;
                  if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
                    post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms);
                  }
                  previous_position_in_ms = current_position_in_ms;
                  go_on = el_false;
                  break;
                case MPG123_NEED_MORE:
                  break;
                default:
                  break;
              }
            } while (done > 0);
          }
        } else {
          // no streaming data, prevent race conditions
          // sleep for a small time (50 ms);
          no_count += 1;
          if (no_count > 10) { 
            post_event(mp3_info->client_notification, AUDIO_BUFFERING, current_position_in_ms);
          }
          sleep_ms(50);
        }
      } 
    }
    
    if (playing) {
      if (audio_event_fifo_peek(mp3_info->player_control) != NULL) {
        event = audio_event_fifo_dequeue(mp3_info->player_control);
      } else {
        event = (audio_event_t*) mc_malloc(sizeof(audio_event_t));
        event->state = INTERNAL_CMD_NONE;
        event->position_in_ms = -1;
      }
    } else {
      //log_debug("waiting for next event");
      event = audio_event_fifo_dequeue(mp3_info->player_control);
    }
  }

  // destroy event received
  log_debug("destroy event received");
  
  // Kill playing streams
  if (mp3_info->streaming) {
    mp3_info->continue_streaming = el_false;
    psem_wait(mp3_info->stream_ready);
  }
  
  audio_event_destroy(event);

  // exit thread  
  return NULL;
}