Exemplo n.º 1
0
static xmlNodePtr
bt_song_info_persistence_save (const BtPersistence * const persistence,
    xmlNodePtr const parent_node)
{
  const BtSongInfo *const self = BT_SONG_INFO (persistence);
  xmlNodePtr node = NULL;

  GST_DEBUG ("PERSISTENCE::song-info");

  if ((node = xmlNewChild (parent_node, NULL, XML_CHAR_PTR ("meta"), NULL))) {
    if (!strcmp (self->priv->name, DEFAULT_SONG_NAME)) {
      gchar *file_path = NULL, *file_name, *ext;

      bt_child_proxy_get (self->priv->song, "song-io::file-name", &file_path,
          NULL);
      if (file_path) {
        file_name = g_path_get_basename (file_path);
        if ((ext = strrchr (file_name, '.'))) {
          *ext = '\0';
        }
        GST_INFO ("using '%s' instead of default title", file_name);
        g_object_set ((gpointer) self, "name", file_name, NULL);
        g_free (file_name);
        g_free (file_path);
      }
    }

    if (self->priv->info) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("info"),
          XML_CHAR_PTR (self->priv->info));
    }
    if (self->priv->name) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("name"),
          XML_CHAR_PTR (self->priv->name));
    }
    if (self->priv->genre) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("genre"),
          XML_CHAR_PTR (self->priv->genre));
    }
    if (self->priv->author) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("author"),
          XML_CHAR_PTR (self->priv->author));
    }
    if (self->priv->create_dts) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("create-dts"),
          XML_CHAR_PTR (self->priv->create_dts));
    }
    if (self->priv->change_dts) {
      xmlNewChild (node, NULL, XML_CHAR_PTR ("change-dts"),
          XML_CHAR_PTR (self->priv->change_dts));
    }
    xmlNewChild (node, NULL, XML_CHAR_PTR ("bpm"),
        XML_CHAR_PTR (bt_str_format_ulong (self->priv->beats_per_minute)));
    xmlNewChild (node, NULL, XML_CHAR_PTR ("tpb"),
        XML_CHAR_PTR (bt_str_format_ulong (self->priv->ticks_per_beat)));
    xmlNewChild (node, NULL, XML_CHAR_PTR ("bars"),
        XML_CHAR_PTR (bt_str_format_ulong (self->priv->bars)));
  }
  return node;
}
Exemplo n.º 2
0
static void
bt_song_info_get_property (GObject * const object, const guint property_id,
    GValue * const value, GParamSpec * const pspec)
{
  const BtSongInfo *const self = BT_SONG_INFO (object);
  return_if_disposed ();
  switch (property_id) {
    case SONG_INFO_SONG:
      g_value_set_object (value, self->priv->song);
      break;
    case SONG_INFO_TAGLIST:
      g_value_set_pointer (value, gst_tag_list_copy (self->priv->taglist));
      break;
    case SONG_INFO_FILE_NAME:
      g_value_set_string (value, self->priv->file_name);
      break;
    case SONG_INFO_INFO:
      g_value_set_string (value, self->priv->info);
      break;
    case SONG_INFO_NAME:
      g_value_set_string (value, self->priv->name);
      break;
    case SONG_INFO_GENRE:
      g_value_set_string (value, self->priv->genre);
      break;
    case SONG_INFO_AUTHOR:
      g_value_set_string (value, self->priv->author);
      break;
    case SONG_INFO_BPM:
      g_value_set_ulong (value, self->priv->beats_per_minute);
      break;
    case SONG_INFO_TPB:
      g_value_set_ulong (value, self->priv->ticks_per_beat);
      break;
    case SONG_INFO_BARS:
      g_value_set_ulong (value, self->priv->bars);
      break;
    case SONG_INFO_CREATE_DTS:
      g_value_set_string (value, self->priv->create_dts);
      break;
    case SONG_INFO_CHANGE_DTS:
      g_value_set_string (value, self->priv->change_dts);
      break;
    case SONG_INFO_TICK_DURATION:
      g_value_set_uint64 (value, self->priv->tick_duration);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Exemplo n.º 3
0
static void
bt_song_info_dispose (GObject * const object)
{
  const BtSongInfo *const self = BT_SONG_INFO (object);

  return_if_disposed ();
  self->priv->dispose_has_run = TRUE;

  GST_DEBUG ("!!!! self=%p", self);
  g_object_try_weak_unref (self->priv->song);
  gst_tag_list_unref (self->priv->taglist);

  G_OBJECT_CLASS (bt_song_info_parent_class)->dispose (object);
}
Exemplo n.º 4
0
static void
test_bt_song_info_tick_to_time (BT_TEST_ARGS)
{
  BT_TEST_START;
  GST_INFO ("-- arrange --");
  BtSongInfo *song_info =
      BT_SONG_INFO (check_gobject_get_object_property (song, "song-info"));
  g_object_set (song_info, "bpm", 250L, "tpb", 16L, NULL);

  GST_INFO ("-- act --");
  GstClockTime ts = bt_song_info_tick_to_time (song_info, 8);

  GST_INFO ("-- assert --");
  ck_assert_int_eq (ts, 120 * GST_MSECOND);

  GST_INFO ("-- cleanup --");
  g_object_unref (song_info);
  BT_TEST_END;
}
Exemplo n.º 5
0
static void
bt_song_info_finalize (GObject * const object)
{
  const BtSongInfo *const self = BT_SONG_INFO (object);

  GST_DEBUG ("!!!! self=%p", self);

  g_date_free (self->priv->tag_date);

  g_free (self->priv->file_name);
  g_free (self->priv->info);
  g_free (self->priv->name);
  g_free (self->priv->genre);
  g_free (self->priv->author);
  g_free (self->priv->create_dts);
  g_free (self->priv->change_dts);

  G_OBJECT_CLASS (bt_song_info_parent_class)->finalize (object);
}
Exemplo n.º 6
0
static void
test_bt_song_info_date_stamps (BT_TEST_ARGS)
{
  BT_TEST_START;
  GST_INFO ("-- arrange --");
  BtSongInfo *song_info =
      BT_SONG_INFO (check_gobject_get_object_property (song, "song-info"));

  GST_INFO ("-- act --");
  gchar *create_dts = check_gobject_get_str_property (song_info, "create-dts");

  GST_INFO ("-- assert --");
  fail_unless (create_dts != NULL, NULL);
  ck_assert_gobject_str_eq (song_info, "change-dts", create_dts);

  GST_INFO ("-- cleanup --");
  g_free (create_dts);
  g_object_unref (song_info);
  BT_TEST_END;
}
Exemplo n.º 7
0
static void
test_bt_song_info_seconds_since_last_saved (BT_TEST_ARGS)
{
  BT_TEST_START;
  GST_INFO ("-- arrange --");
  BtSongInfo *song_info =
      BT_SONG_INFO (check_gobject_get_object_property (song, "song-info"));

  GST_INFO ("-- act --");
  // TODO: waiting one sec makes this the slowest test :/
  g_usleep (G_USEC_PER_SEC);
  gint ts = bt_song_info_get_seconds_since_last_saved (song_info);

  GST_INFO ("-- assert --");
  ck_assert_int_gt (ts, 0);

  GST_INFO ("-- cleanup --");
  g_object_unref (song_info);
  BT_TEST_END;
}
Exemplo n.º 8
0
static BtPersistence *
bt_song_info_persistence_load (const GType type,
    const BtPersistence * const persistence, xmlNodePtr node, GError ** err,
    va_list var_args)
{
  const BtSongInfo *const self = BT_SONG_INFO (persistence);

  GST_DEBUG ("PERSISTENCE::song-info");
  g_assert (node);

  for (node = node->children; node; node = node->next) {
    if (!xmlNodeIsText (node)) {
      xmlNodePtr const child_node = node->children;
      if (child_node && xmlNodeIsText (child_node)
          && !xmlIsBlankNode (child_node)) {
        xmlChar *const elem = xmlNodeGetContent (child_node);
        if (elem) {
          const gchar *const property_name = (gchar *) node->name;
          GST_DEBUG ("  \"%s\"=\"%s\"", property_name, elem);
          // depending on the name of the property, treat it's type
          if (!strncmp (property_name, "info", 4) ||
              !strncmp (property_name, "name", 4) ||
              !strncmp (property_name, "genre", 5) ||
              !strncmp (property_name, "author", 6) ||
              !strncmp (property_name, "create-dts", 10) ||
              !strncmp (property_name, "change-dts", 10)
              ) {
            g_object_set ((gpointer) self, property_name, elem, NULL);
          } else if (!strncmp (property_name, "bpm", 3) ||
              !strncmp (property_name, "tpb", 3) ||
              !strncmp (property_name, "bars", 4)) {
            g_object_set ((gpointer) self, property_name, atol ((char *) elem),
                NULL);
          }
          xmlFree (elem);
        }
      }
    }
  }
  return BT_PERSISTENCE (persistence);
}
Exemplo n.º 9
0
static void
test_bt_machine_state_not_overridden (BT_TEST_ARGS)
{
  BT_TEST_START;
  GST_INFO ("-- arrange --");
  BtSequence *sequence =
      (BtSequence *) check_gobject_get_object_property (song, "sequence");
  BtSongInfo *song_info =
      BT_SONG_INFO (check_gobject_get_object_property (song, "song-info"));
  BtMachine *src = BT_MACHINE (bt_source_machine_new (song, "gen",
          "simsyn", 0L, NULL));
  BtMachine *sink = BT_MACHINE (bt_sink_machine_new (song, "sink", NULL));
  bt_wire_new (song, src, sink, NULL);
  BtCmdPattern *pattern = bt_cmd_pattern_new (song, src, BT_PATTERN_CMD_SOLO);
  GstElement *element =
      (GstElement *) check_gobject_get_object_property (src, "machine");

  /* duration: 0:00:00.480000000 */
  g_object_set (song_info, "bpm", 250L, "tpb", 16L, NULL);
  g_object_set (sequence, "length", 32L, NULL);
  bt_sequence_add_track (sequence, src, -1);
  bt_sequence_set_pattern (sequence, 4, 0, pattern);
  g_object_set (element, "wave", /* silence */ 4, NULL);

  GST_INFO ("-- act --");
  g_object_set (src, "state", BT_MACHINE_STATE_MUTE, NULL);
  bt_machine_update_default_state_value (src);
  bt_song_play (song);
  check_run_main_loop_until_eos_or_error (song);

  GST_INFO ("-- assert --");
  ck_assert_gobject_guint_eq (src, "state", BT_MACHINE_STATE_MUTE);

  GST_INFO ("-- cleanup --");
  gst_object_unref (element);
  g_object_unref (pattern);
  g_object_unref (sequence);
  g_object_unref (song_info);
  BT_TEST_END;
}
Exemplo n.º 10
0
static void
test_bt_song_info_update_tpb (BT_TEST_ARGS)
{
  BT_TEST_START;
  GST_INFO ("-- arrange --");
  GstClockTime t1, t2;
  BtSongInfo *song_info =
      BT_SONG_INFO (check_gobject_get_object_property (song, "song-info"));
  g_object_set (song_info, "tpb", 8, NULL);
  g_object_get (song_info, "tick-duration", &t1, NULL);

  GST_INFO ("-- act --");
  g_object_set (song_info, "tpb", 4, NULL);
  g_object_get (song_info, "tick-duration", &t2, NULL);

  GST_INFO ("-- assert --");
  ck_assert_uint64_eq (t2, t1 + t1);

  GST_INFO ("-- cleanup --");
  g_object_unref (song_info);
  BT_TEST_END;
}
Exemplo n.º 11
0
static void
bt_song_info_set_property (GObject * const object, const guint property_id,
    const GValue * const value, GParamSpec * const pspec)
{
  const BtSongInfo *const self = BT_SONG_INFO (object);
  return_if_disposed ();
  switch (property_id) {
    case SONG_INFO_SONG:
      self->priv->song = BT_SONG (g_value_get_object (value));
      g_object_try_weak_ref (self->priv->song);
      GST_DEBUG ("set the song for song-info: %p", self->priv->song);
      break;
    case SONG_INFO_FILE_NAME:
      g_free (self->priv->file_name);
      self->priv->file_name = g_value_dup_string (value);
      GST_DEBUG ("set the file-name for song_info: %s", self->priv->file_name);
      break;
    case SONG_INFO_INFO:{
      const gchar *str = g_value_get_string (value);
      if ((self->priv->info != str) && (!self->priv->info || !str
              || strcmp (self->priv->info, str))) {
        g_free (self->priv->info);
        if (str) {
          self->priv->info = g_value_dup_string (value);
          gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_DESCRIPTION, self->priv->info, NULL);
        } else {
          self->priv->info = NULL;
          gst_tag_list_remove_tag (self->priv->taglist, GST_TAG_DESCRIPTION);
        }
        GST_DEBUG ("set the info for song_info: %s", self->priv->info);
      }
      break;
    }
    case SONG_INFO_NAME:{
      const gchar *str = g_value_get_string (value);
      if ((self->priv->name != str) && (!self->priv->name || !str
              || strcmp (self->priv->name, str))) {
        g_free (self->priv->name);
        if (str) {
          self->priv->name = g_value_dup_string (value);
          gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_TITLE, self->priv->name, NULL);
        } else {
          self->priv->name = NULL;
          gst_tag_list_remove_tag (self->priv->taglist, GST_TAG_TITLE);
        }
        GST_DEBUG ("set the name for song_info: %s", self->priv->name);
      }
      break;
    }
    case SONG_INFO_GENRE:{
      const gchar *str = g_value_get_string (value);
      if ((self->priv->genre != str) && (!self->priv->genre || !str
              || strcmp (self->priv->genre, str))) {
        g_free (self->priv->genre);
        if (str) {
          self->priv->genre = g_value_dup_string (value);
          gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_GENRE, self->priv->genre, NULL);
        } else {
          self->priv->genre = NULL;
          gst_tag_list_remove_tag (self->priv->taglist, GST_TAG_GENRE);
        }
        GST_DEBUG ("set the genre for song_info: %s", self->priv->genre);
      }
      break;
    }
    case SONG_INFO_AUTHOR:{
      const gchar *str = g_value_get_string (value);
      if ((self->priv->author != str) && (!self->priv->author || !str
              || strcmp (self->priv->author, str))) {
        g_free (self->priv->author);
        if (str) {
          self->priv->author = g_value_dup_string (value);
          gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_ARTIST, self->priv->author, NULL);
        } else {
          self->priv->author = NULL;
          gst_tag_list_remove_tag (self->priv->taglist, GST_TAG_ARTIST);
        }
        GST_DEBUG ("set the author for song_info: %s", self->priv->author);
      }
      break;
    }
    case SONG_INFO_BPM:{
      gulong val = g_value_get_ulong (value);
      if (self->priv->beats_per_minute != val) {
        self->priv->beats_per_minute = val;
        gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_BEATS_PER_MINUTE, (gdouble) self->priv->beats_per_minute,
            NULL);
        bt_song_info_tempo_changed (self);
        GST_DEBUG ("set the bpm for song_info: %lu",
            self->priv->beats_per_minute);
      }
      break;
    }
    case SONG_INFO_TPB:{
      gulong val = g_value_get_ulong (value);
      if (self->priv->ticks_per_beat != val) {
        self->priv->ticks_per_beat = val;
        bt_song_info_tempo_changed (self);
        GST_DEBUG ("set the tpb for song_info: %lu",
            self->priv->ticks_per_beat);
      }
    }
      break;
    case SONG_INFO_BARS:{
      gulong val = g_value_get_ulong (value);
      if (self->priv->bars != val) {
        self->priv->bars = val;
        bt_song_info_tempo_changed (self);
        GST_DEBUG ("set the bars for song_info: %lu", self->priv->bars);
      }
      break;
    }
    case SONG_INFO_CREATE_DTS:{
      const gchar *const dts = g_value_get_string (value);

      if (dts) {
        if (strlen (dts) == DTS_LEN) {
          strcpy (self->priv->create_dts, dts);
        }
      } else {
        time_t now = time (NULL);
        /* this is ISO 8601 Date and Time Format
         * %F     Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)
         * %T     The time in 24-hour notation (%H:%M:%S). (SU)
         */
        strftime (self->priv->create_dts, DTS_LEN + 1, "%FT%TZ", gmtime (&now));
      }
      break;
    }
    case SONG_INFO_CHANGE_DTS:{
      const gchar *const dts = g_value_get_string (value);

      if (dts) {
        if (strlen (dts) == DTS_LEN) {
          struct tm tm = { 0, };
          strcpy (self->priv->change_dts, dts);
          // parse date and update tag
          strptime (dts, "%FT%TZ", &tm);
          g_date_set_time_t (self->priv->tag_date, mktime (&tm));
          gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
              GST_TAG_DATE, self->priv->tag_date, NULL);
        }
      } else {
        time_t now = time (NULL);
        strftime (self->priv->change_dts, DTS_LEN + 1, "%FT%TZ", gmtime (&now));
        g_date_set_time_t (self->priv->tag_date, now);
        gst_tag_list_add (self->priv->taglist, GST_TAG_MERGE_REPLACE,
            GST_TAG_DATE, self->priv->tag_date, NULL);
      }
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Exemplo n.º 12
0
/**
 * bt_song_info_new:
 * @song: the song the new instance belongs to
 *
 * Create a new instance
 *
 * Returns: the new instance or %NULL in case of an error
 */
BtSongInfo *
bt_song_info_new (const BtSong * const song)
{
  return BT_SONG_INFO (g_object_new (BT_TYPE_SONG_INFO, "song", song, NULL));
}