Blame src/cddb.c

Packit dd8086
/*
Packit dd8086
  Copyright (C) 2005, 2008, 2009, 2011 Rocky Bernstein <rocky@gnu.org>
Packit dd8086
  
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
# define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/audio.h>
Packit dd8086
#include "cddb.h"
Packit dd8086
Packit dd8086
cddb_opts_t cddb_opts;
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Returns the sum of the decimal digits in a number. Eg. 1955 = 20
Packit dd8086
*/
Packit dd8086
static int
Packit dd8086
cddb_dec_digit_sum(int n)
Packit dd8086
{
Packit dd8086
  int ret=0;
Packit dd8086
  
Packit dd8086
  for (;;) {
Packit dd8086
    ret += n%10;
Packit dd8086
    n    = n/10;
Packit dd8086
    if (!n) return ret;
Packit dd8086
  }
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Compute the CDDB disk ID for an Audio disk.  This is a funny checksum
Packit dd8086
   consisting of the concatenation of 3 things:
Packit dd8086
      the sum of the decimal digits of sizes of all tracks, 
Packit dd8086
      the total length of the disk, and 
Packit dd8086
      the number of tracks.
Packit dd8086
*/
Packit dd8086
uint32_t
Packit dd8086
cddb_discid(CdIo_t *p_cdio, track_t i_tracks)
Packit dd8086
{
Packit dd8086
  int i,t,n=0;
Packit dd8086
  msf_t start_msf;
Packit dd8086
  msf_t msf;
Packit dd8086
  
Packit dd8086
  for (i = 1; i <= i_tracks; i++) {
Packit dd8086
    cdio_get_track_msf(p_cdio, i, &msf;;
Packit dd8086
    n += cddb_dec_digit_sum(cdio_audio_get_msf_seconds(&msf));
Packit dd8086
  }
Packit dd8086
Packit dd8086
  cdio_get_track_msf(p_cdio, 1, &start_msf);
Packit dd8086
  cdio_get_track_msf(p_cdio, CDIO_CDROM_LEADOUT_TRACK, &msf;;
Packit dd8086
  
Packit dd8086
  t = cdio_audio_get_msf_seconds(&msf)-cdio_audio_get_msf_seconds(&start_msf);
Packit dd8086
  
Packit dd8086
  return ((n % 0xff) << 24 | t << 8 | i_tracks);
Packit dd8086
}
Packit dd8086
Packit dd8086
#ifdef HAVE_CDDB
Packit dd8086
bool 
Packit dd8086
init_cddb(CdIo_t *p_cdio, cddb_conn_t **pp_conn, cddb_disc_t **pp_cddb_disc, 
Packit dd8086
	  error_fn_t errmsg, track_t i_first_track, track_t i_tracks,
Packit dd8086
	  int *i_cddb_matches)
Packit dd8086
{
Packit dd8086
  track_t i;
Packit dd8086
  
Packit dd8086
  *pp_conn =  cddb_new();
Packit dd8086
  *pp_cddb_disc = NULL;
Packit dd8086
  
Packit dd8086
  if (!*pp_conn) {
Packit dd8086
    errmsg("unable to initialize libcddb");
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  
Packit dd8086
  if (NULL == cddb_opts.email) 
Packit dd8086
    cddb_set_email_address(*pp_conn, "me@home");
Packit dd8086
  else 
Packit dd8086
    cddb_set_email_address(*pp_conn, cddb_opts.email);
Packit dd8086
  
Packit dd8086
  if (NULL == cddb_opts.server) 
Packit dd8086
    cddb_set_server_name(*pp_conn, "freedb.freedb.org");
Packit dd8086
  else 
Packit dd8086
    cddb_set_server_name(*pp_conn, cddb_opts.server);
Packit dd8086
  
Packit dd8086
  if (cddb_opts.timeout >= 0) 
Packit dd8086
    cddb_set_timeout(*pp_conn, cddb_opts.timeout);
Packit dd8086
  
Packit dd8086
  cddb_set_server_port(*pp_conn, cddb_opts.port);
Packit dd8086
  
Packit dd8086
  if (cddb_opts.http) 
Packit dd8086
    cddb_http_enable(*pp_conn);
Packit dd8086
  else 
Packit dd8086
    cddb_http_disable(*pp_conn);
Packit dd8086
  
Packit dd8086
  if (NULL != cddb_opts.cachedir) 
Packit dd8086
    cddb_cache_set_dir(*pp_conn, cddb_opts.cachedir);
Packit dd8086
  
Packit dd8086
  if (cddb_opts.disable_cache) 
Packit dd8086
    cddb_cache_disable(*pp_conn);
Packit dd8086
  
Packit dd8086
  *pp_cddb_disc = cddb_disc_new();
Packit dd8086
  if (!*pp_cddb_disc) {
Packit dd8086
    errmsg("unable to create CDDB disc structure");
Packit dd8086
    cddb_destroy(*pp_conn);
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  for(i = 0; i < i_tracks; i++) {
Packit dd8086
    cddb_track_t *t = cddb_track_new(); 
Packit dd8086
    cddb_track_set_frame_offset(t, 
Packit dd8086
				cdio_get_track_lba(p_cdio, i+i_first_track));
Packit dd8086
    cddb_disc_add_track(*pp_cddb_disc, t);
Packit dd8086
  }
Packit dd8086
  
Packit dd8086
  cddb_disc_set_length(*pp_cddb_disc, 
Packit dd8086
		       cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK) 
Packit dd8086
		       / CDIO_CD_FRAMES_PER_SEC);
Packit dd8086
  
Packit dd8086
  if (!cddb_disc_calc_discid(*pp_cddb_disc)) {
Packit dd8086
    errmsg("libcddb calc discid failed.");
Packit dd8086
    cddb_destroy(*pp_conn);
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  
Packit dd8086
  *i_cddb_matches = cddb_query(*pp_conn, *pp_cddb_disc);
Packit dd8086
  
Packit dd8086
  if (-1 == *i_cddb_matches) 
Packit dd8086
    errmsg(cddb_error_str(cddb_errno(*pp_conn)));
Packit dd8086
Packit dd8086
  cddb_read(*pp_conn, *pp_cddb_disc);
Packit dd8086
  return true;
Packit dd8086
}
Packit dd8086
#endif /*HAVE_CDDB*/