Changeset 852

Show
Ignore:
Timestamp:
02/25/08 18:06:00 (9 months ago)
Author:
michux
Message:

update mpd plugin to v0.8 - makefile needs some work now

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/plugin_mpd.c

    r850 r852  
    22 * $URL$ 
    33 * 
    4  * mpd informations v0.7 
     4 * mpd informations v0.8 
    55 * 
    66 * Copyright (C) 2006 Stefan Kuhne <sk-privat@gmx.net> 
     
    2828 
    2929/*  
    30  * exported functions: 
    31  * 
    32  * int plugin_init_sample (void) 
    33  *  adds various functions 
    34  * 
    3530 * changelog v0.5 (20.11.2007): 
    3631 *   changed:   mpd::artist(), mpd::title(), mpd::album() 
     
    6257 *               -> uses less ressources 
    6358 * 
     59 * changelog v0.8 (30.01.2007): 
     60 *  changed:  -libmpd is not needed anymore, use libmpdclient.c instead 
     61 *  fixed:    -getMpdUptime() 
     62 *            -getMpdPlaytime() 
     63 *            -type definition 
     64 *  added:    -mpd::getSamplerateHz 
     65 *            -getAudioChannels 
    6466 */ 
    6567 
     
    6769 
    6870TODO:  
    69  -what happens if the db is updating? int mpd_status_db_is_updating() 0/1 
    70  
    71 BUGS: 
    72  -getMpdUptime() does not update its counter 
    73  -getMpdPlaytime() does not update its counter 
     71 -what happens if the db is updating?  
    7472 
    7573*/ 
     
    8785#include <sys/time.h> 
    8886 
    89  
    90 /* you need libmpd to compile this plugin! http://sarine.nl/libmpd */ 
    91 #include <libmpd/libmpd.h> 
     87//source: http://www.musicpd.org/libmpdclient.shtml 
     88#include "libmpdclient.h" 
    9289 
    9390#ifdef WITH_DMALLOC 
     
    9693 
    9794/* current song */ 
    98 #define TAGLEN 512 
    99 #define MAX_PATH 1024 
    100 static char *artist[TAGLEN]; 
    101 static char *album[TAGLEN]; 
    102 static char *title[TAGLEN]; 
    103 static char *filename[MAX_PATH]; 
    104 static long l_totalTimeSec; 
    105 static long l_elapsedTimeSec; 
     95 
     96static int l_totalTimeSec; 
     97static int l_elapsedTimeSec; 
    10698static int l_bitRate; 
    10799static int l_repeatEnabled; 
     
    109101static int l_state; 
    110102static int l_volume; 
    111 static int l_songsInDb; 
    112 static long l_mpdUptime; 
    113 static long l_mpdPlaytime; 
    114 static long l_mpdDbPlaytime; 
    115 static long l_mpdPlaylistLength; 
     103static int l_numberOfSongs; 
     104static unsigned long l_uptime; 
     105static unsigned long l_playTime; 
     106static unsigned long l_dbPlayTime; 
     107static int l_playlistLength; 
     108/* pos in playlist */ 
    116109static int l_currentSongPos; 
     110static unsigned int l_sampleRate;    
     111static int l_channels;   
     112 
     113static mpd_Song *currentSong; 
    117114 
    118115/* connection information */ 
     
    123120struct timeval timestamp; 
    124121 
    125 static MpdObj *mi = NULL; 
     122static mpd_Connection * conn; 
    126123static char Section[] = "Plugin:MPD"; 
    127124 
    128  
    129 static void error_callback( __attribute__ ((unused)) MpdObj * mi, int errorid, char *msg, __attribute__ ((unused)) 
    130         void *userdata) 
    131 { 
    132     debug("[MPD] caught error %i: '%s'", errorid, msg); 
    133 } 
    134125 
    135126 
     
    175166 
    176167    debug("[MPD] connection detail: [%s:%d]", host, iport); 
    177  
    178     mi = mpd_new(host, iport, pw); 
    179     mpd_signal_connect_error(mi, (ErrorCallback) error_callback, NULL); 
    180     mpd_set_connection_timeout(mi, 5); 
    181  
    182     configured = 1; 
     168    configured = 1;     
     169     
     170    //test connection - if it fails i dont care 
     171    conn = mpd_newConnection(host, iport, 10); 
     172    if(conn->error) { 
     173      error("[MPD] error mpd_newConnection: %s", conn->errorStr); 
     174      mpd_closeConnection(conn); 
     175      //return -1; 
     176    } 
     177   
    183178    return configured; 
    184179} 
     
    187182static int mpd_update() 
    188183{ 
    189     int ret = -1; 
    190     mpd_Song *song; 
    191     static char *notagArt = "No artist tag"; 
    192     static char *notagTit = "No title tag"; 
    193     static char *notagAlb = "No album tag"; 
    194     static char *nofilename = "No Filename"; 
    195     struct timeval now; 
    196     int len; 
     184    int ret = -1;     
     185    struct timeval now;     
     186 
     187    /* reread every 1000 msec only */ 
     188    gettimeofday(&now, NULL);     
     189    int timedelta = (now.tv_sec - timestamp.tv_sec) * 1000 + (now.tv_usec - timestamp.tv_usec) / 1000; 
     190    if (timedelta < waittime) {       
     191  return 1; 
     192    }     
    197193 
    198194    //check if configured 
     
    201197    } 
    202198 
    203     /* reread every 1000 msec only */ 
    204     gettimeofday(&now, NULL);     
    205     int timedelta = (now.tv_sec - timestamp.tv_sec) * 1000 + (now.tv_usec - timestamp.tv_usec) / 1000; 
    206     if (timedelta < waittime) { 
    207   return 1; 
    208     } 
    209  
    210     //debug("[MPD] time delta: %i", timedelta); 
    211  
    212     //send password if enabled 
    213     if (pw[0] != 0) 
    214   mpd_send_password(mi); 
    215      
    216199    //check if connected 
    217     if (mpd_check_connected(mi) != 1) { 
    218   debug("[MPD] not connected, try to reconnect..."); 
    219   mpd_connect(mi); 
     200    if(conn->error) { 
     201      debug("[MPD] not connected, try to reconnect..."); 
     202      mpd_closeConnection(conn); 
     203      conn = mpd_newConnection(host, iport, 10); 
     204 
     205      if(conn->error) { 
     206        error("[MPD] connection failed, give up..."); 
     207        return -1; 
     208      } 
     209       
     210      debug("[MPD] connection ok..."); 
     211    }     
     212     
     213    mpd_Status * status=NULL; 
     214    mpd_Stats *stats=NULL; 
     215    mpd_InfoEntity * entity; 
     216     
     217    mpd_sendCommandListOkBegin(conn); 
     218    mpd_sendStatsCommand(conn);  
     219    mpd_sendStatusCommand(conn); 
     220    mpd_sendCurrentSongCommand(conn); 
     221    mpd_sendCommandListEnd(conn); 
     222 
     223//stats 
     224    stats = mpd_getStats(conn); 
     225    if(stats==NULL) {      
     226  error("[MPD] error mpd_getStats: %s", conn->errorStr); 
     227  goto cleanup; 
     228    }   
     229 
     230//status 
     231    mpd_nextListOkCommand(conn);     
     232    if((status = mpd_getStatus(conn))==NULL) { 
     233  error("[MPD] error mpd_nextListOkCommand: %s", conn->errorStr); 
     234  goto cleanup; 
     235    } 
     236     
     237//song     
     238    mpd_nextListOkCommand(conn); 
     239    while((entity = mpd_getNextInfoEntity(conn))) { 
     240  mpd_Song * song = entity->info.song; 
     241 
     242  if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) { 
     243      mpd_freeInfoEntity(entity); 
     244      continue; 
     245  } 
     246  if (currentSong!=NULL) 
     247          mpd_freeSong(currentSong); 
    220248   
    221   if (mpd_check_connected(mi) != 1) { 
    222       debug("[MPD] connection failed, give up..."); 
    223       return -1; 
    224   } 
    225   debug("[MPD] connection ok..."); 
    226     } 
    227  
    228     ret = 0; 
    229      
    230     mpd_status_update(mi); 
    231  
    232     l_elapsedTimeSec  = mpd_status_get_elapsed_song_time(mi); 
    233     l_bitRate     = mpd_status_get_bitrate(mi); 
    234     l_totalTimeSec  = mpd_status_get_total_song_time(mi); 
    235     l_repeatEnabled = mpd_player_get_repeat(mi); 
    236     l_randomEnabled   = mpd_player_get_random(mi); 
    237     l_state     = mpd_player_get_state(mi); 
    238     l_volume    = mpd_status_get_volume(mi); 
    239     l_songsInDb   = mpd_stats_get_total_songs(mi); 
    240     l_mpdUptime   = mpd_stats_get_uptime(mi); 
    241     l_mpdPlaytime   = mpd_stats_get_playtime(mi); 
    242     l_mpdDbPlaytime   = mpd_stats_get_db_playtime(mi); 
    243     l_mpdPlaylistLength = mpd_playlist_get_playlist_length(mi); 
    244     l_currentSongPos  = mpd_player_get_current_song_pos(mi); 
    245  
     249  currentSong = mpd_songDup(song); 
     250  mpd_freeInfoEntity(entity); 
     251    } 
     252     
     253    l_elapsedTimeSec  = status->elapsedTime; 
     254    l_totalTimeSec  = status->totalTime; 
     255    l_repeatEnabled = status->repeat; 
     256    l_randomEnabled   = status->random; 
     257    l_bitRate     = status->bitRate;     
     258    l_state     = status->state; 
     259    l_volume    = status->volume; 
     260    l_playlistLength  = status->playlistLength; 
     261    l_currentSongPos  = status->song+1; 
     262    l_sampleRate  = status->sampleRate; 
     263    l_channels    = status->channels; 
     264     
     265    l_numberOfSongs   = stats->numberOfSongs; 
     266    l_uptime    = stats->uptime; 
     267    l_playTime    = stats->playTime; 
     268    l_dbPlayTime  = stats->dbPlayTime; 
     269 
     270     
    246271    /* sanity checks */ 
    247272    if (l_volume < 0 || l_volume > 100) 
     
    251276  l_bitRate = 0; 
    252277   
    253     song = mpd_playlist_get_current_song(mi); 
    254     if (song) { 
    255  
    256       /* copy song information to local variables */ 
    257       memset(album, 0, TAGLEN); 
    258       if (song->album != 0) { 
    259     len = strlen(song->album); 
    260     if (len > TAGLEN) 
    261         len = TAGLEN; 
    262     memcpy(album, song->album, len); 
    263  
    264       } else 
    265     memcpy(album, notagAlb, strlen(notagAlb)); 
    266  
    267       memset(artist, 0, TAGLEN); 
    268       if (song->artist != 0) { 
    269     len = strlen(song->artist); 
    270     if (len > TAGLEN) 
    271         len = TAGLEN; 
    272     memcpy(artist, song->artist, len); 
    273       } else 
    274     memcpy(artist, notagArt, strlen(notagArt)); 
    275  
    276       memset(title, 0, TAGLEN); 
    277       if (song->title != 0) { 
    278     len = strlen(song->title); 
    279     if (len > TAGLEN) 
    280         len = TAGLEN; 
    281     memcpy(title, song->title, len); 
    282       } else 
    283     memcpy(title, notagTit, strlen(notagTit)); 
    284  
    285       memset(filename, 0, MAX_PATH); 
    286       if (song->file != 0) { 
    287     len = strlen(song->file); 
    288     if (len > MAX_PATH) 
    289         len = MAX_PATH; 
    290     memcpy(filename, song->file, len); 
    291       } else 
    292     memcpy(filename, nofilename, strlen(nofilename)); 
    293     } 
    294      
    295 //    mpd_disconnect(mi);   /* you need to disconnect here */ 
     278    if (l_elapsedTimeSec > l_totalTimeSec || l_elapsedTimeSec < 0) 
     279  l_elapsedTimeSec = 0; 
     280    ret = 0; 
     281     
     282cleanup: 
     283    if (stats!=NULL) 
     284  mpd_freeStats(stats); 
     285       
     286    if (status!=NULL)   
     287  mpd_freeStatus(status); 
     288 
     289    if(conn->error) { 
     290  error("[MPD] error: %s", conn->errorStr); 
     291  return -1; 
     292    } 
     293 
     294    mpd_finishCommand(conn); 
     295    if(conn->error) {      
     296  error("[MPD] error mpd_finishCommand: %s", conn->errorStr); 
     297  return -1; 
     298    }  
     299   
    296300    gettimeofday(&timestamp, NULL); 
    297  
    298301    return ret; 
    299302} 
     
    343346} 
    344347 
     348/* if no tag is availabe, use filename */ 
    345349static void getArtist(RESULT * result) 
    346350{ 
    347     int cSong = mpd_update(); 
    348     if (cSong != 0) {   /* inform user this information is cached... */ 
    349 //  debug("[MPD] use cached artist information..."); 
    350     } 
    351     SetResult(&result, R_STRING, artist); 
     351    mpd_update(); 
     352    if (currentSong!=NULL) { 
     353  if (currentSong->artist!=NULL) { 
     354      SetResult(&result, R_STRING, currentSong->artist); 
     355  } else { 
     356      if (currentSong->file!=NULL) 
     357    SetResult(&result, R_STRING, currentSong->file); 
     358      else 
     359    SetResult(&result, R_STRING, ""); 
     360  } 
     361    } else SetResult(&result, R_STRING, ""); 
     362     
    352363} 
    353364 
    354365static void getTitle(RESULT * result) 
    355366{ 
    356     int cSong = mpd_update(); 
    357     if (cSong != 0) {   /* inform user this information is cached... */ 
    358 //  debug("[MPD] use cached title information..."); 
    359     } 
    360     SetResult(&result, R_STRING, title); 
     367    mpd_update(); 
     368    if (currentSong!=NULL) { 
     369  if (currentSong->title!=NULL) { 
     370          SetResult(&result, R_STRING, currentSong->title); 
     371  } else SetResult(&result, R_STRING, ""); 
     372    } else SetResult(&result, R_STRING, ""); 
     373 
    361374} 
    362375 
    363376static void getAlbum(RESULT * result) 
    364377{ 
    365     int cSong = mpd_update(); 
    366     if (cSong != 0) {   /* inform user this information is cached... */ 
    367 //  debug("[MPD] use cached album information..."); 
    368     } 
    369     SetResult(&result, R_STRING, album); 
     378    mpd_update(); 
     379    if (currentSong!=NULL) {     
     380  if (currentSong->album!=NULL) 
     381          SetResult(&result, R_STRING, currentSong->album); 
     382        else  
     383          SetResult(&result, R_STRING, ""); 
     384    }  
     385    else SetResult(&result, R_STRING, ""); 
    370386} 
    371387 
    372388static void getFilename(RESULT * result) 
    373389{ 
    374     int cSong = mpd_update(); 
    375     if (cSong != 0) {   /* inform user this information is cached... */ 
    376 //  debug("[MPD] use cached filename information..."); 
    377     } 
    378     SetResult(&result, R_STRING, filename); 
     390    mpd_update(); 
     391    if (currentSong!=NULL) { 
     392  if (currentSong->file!=NULL) 
     393          SetResult(&result, R_STRING, currentSong->file); 
     394        else  
     395          SetResult(&result, R_STRING, ""); 
     396    }  
     397    else SetResult(&result, R_STRING, ""); 
     398     
    379399} 
    380400 
     
    393413 
    394414    switch (l_state) { 
    395     case MPD_PLAYER_PLAY: 
     415    case MPD_STATUS_STATE_PLAY: 
    396416  ret = 1; 
    397417  break; 
    398     case MPD_PLAYER_PAUSE: 
     418    case MPD_STATUS_STATE_PAUSE: 
    399419  ret = 2; 
    400420  break; 
    401     case MPD_PLAYER_STOP: 
     421    case MPD_STATUS_STATE_STOP: 
    402422  ret = 3; 
    403423  break; 
     
    420440} 
    421441 
    422 /* return the # of songs in thr mpd db .. */ 
     442/* return the # of songs in the mpd db .. */ 
    423443static void getSongsInDb(RESULT * result) 
    424444{ 
    425445    double d; 
    426446    mpd_update(); 
    427     d = (double)l_songsInDb; 
    428     /* return 0..100 or < 0 when failed */ 
     447    d = (double)l_numberOfSongs; 
    429448    SetResult(&result, R_NUMBER, &d); 
    430449} 
     
    434453    double d; 
    435454    mpd_update(); 
    436     d = (double)l_mpdUptime; 
     455    d = (double)l_uptime; 
    437456    SetResult(&result, R_NUMBER, &d); 
    438457} 
     
    442461    double d; 
    443462    mpd_update(); 
    444     d = (double)l_mpdPlaytime; 
     463    d = (double)l_playTime; 
    445464    SetResult(&result, R_NUMBER, &d); 
    446465} 
     
    450469    double d; 
    451470    mpd_update(); 
    452     d = (double)l_mpdDbPlaytime; 
     471    d = (double)l_dbPlayTime; 
    453472    SetResult(&result, R_NUMBER, &d); 
    454473} 
     
    458477    double d; 
    459478    mpd_update(); 
    460     d = (double)l_mpdPlaylistLength; 
     479    d = (double)l_playlistLength; 
    461480    SetResult(&result, R_NUMBER, &d); 
    462481} 
     
    467486    mpd_update(); 
    468487    d = (double)l_currentSongPos; 
     488    SetResult(&result, R_NUMBER, &d); 
     489} 
     490 
     491static void getAudioChannels(RESULT * result) 
     492{ 
     493    double d; 
     494    mpd_update(); 
     495    d = (double)l_channels; 
     496    SetResult(&result, R_NUMBER, &d); 
     497} 
     498 
     499static void getSamplerateHz(RESULT * result) 
     500{ 
     501    double d; 
     502    mpd_update(); 
     503    d = (double)l_sampleRate; 
    469504    SetResult(&result, R_NUMBER, &d); 
    470505} 
     
    516551{ 
    517552    int check; 
    518     debug("[MPD] v0.7, check lcd4linux configuration file..."); 
     553    debug("[MPD] v0.8, check lcd4linux configuration file..."); 
    519554 
    520555    check = configure_mpd(); 
    521556    if (check) 
    522   debug("[MPD] done"); 
     557  debug("[MPD] connected!"); 
    523558    else 
    524   debug("[MPD] error!"); 
    525  
    526     memset(album, 0, TAGLEN); 
    527     memset(artist, 0, TAGLEN); 
    528     memset(title, 0, TAGLEN); 
    529     memset(filename, 0, MAX_PATH); 
     559  debug("[MPD] error, NOT connected!"); 
    530560     
    531561    gettimeofday(&timestamp, NULL);  
     
    538568    AddFunction("mpd::elapsedTimeSec", 0, elapsedTimeSec); 
    539569    AddFunction("mpd::bitRate", 0, bitRate); 
     570    AddFunction("mpd::getSamplerateHz", 0, getSamplerateHz); 
     571    AddFunction("mpd::getAudioChannels", 0, getAudioChannels); 
    540572    AddFunction("mpd::getRepeatInt", 0, getRepeatInt); 
    541573    AddFunction("mpd::getRandomInt", 0, getRandomInt); 
     
    559591{ 
    560592    debug("[MPD] disconnect from mpd"); 
    561     mpd_free(mi); 
    562 } 
     593    if (currentSong!=NULL) 
     594  mpd_freeSong(currentSong); 
     595    mpd_closeConnection(conn); 
     596}