/* * check if we can disconnect a src machine from a sink while playing. */ static void test_bt_setup_dynamic_rem_src (BT_TEST_ARGS) { BT_TEST_START; GST_INFO ("-- arrange --"); BtSetup *setup = (BtSetup *) check_gobject_get_object_property (song, "setup"); BtSequence *sequence = (BtSequence *) check_gobject_get_object_property (song, "sequence"); BtMachine *sink = BT_MACHINE (bt_sink_machine_new (song, "master", NULL)); BtMachine *gen1 = BT_MACHINE (bt_source_machine_new (song, "gen1", "audiotestsrc", 0L, NULL)); BtMachine *gen2 = BT_MACHINE (bt_source_machine_new (song, "gen2", "audiotestsrc", 0L, NULL)); bt_wire_new (song, gen1, sink, NULL); BtWire *wire2 = bt_wire_new (song, gen2, sink, NULL); GstElement *element1 = (GstElement *) check_gobject_get_object_property (gen1, "machine"); GstElement *element2 = (GstElement *) check_gobject_get_object_property (gen2, "machine"); g_object_set (sequence, "length", 64L, "loop", TRUE, NULL); bt_sequence_add_track (sequence, gen1, -1); bt_sequence_add_track (sequence, gen2, -1); g_object_set (element1, "wave", /* silence */ 4, NULL); g_object_set (element2, "wave", /* silence */ 4, NULL); bt_machine_set_param_defaults (gen1); bt_machine_set_param_defaults (gen2); mark_point (); /* play the song */ if (bt_song_play (song)) { mark_point (); check_run_main_loop_until_playing_or_error (song); GST_DEBUG ("song plays"); /* unlink machines */ bt_setup_remove_wire (setup, wire2); GST_DEBUG ("wire removed"); g_usleep (G_USEC_PER_SEC / 10); /* stop the song */ bt_song_stop (song); } else { fail ("playing of song failed"); } GST_INFO ("-- cleanup --"); g_object_unref (setup); g_object_unref (sequence); BT_TEST_END; }
/* test recording (loop test over BtSinkBinRecordFormat */ static void test_bt_sink_bin_record (BT_TEST_ARGS) { BT_TEST_START; GST_INFO ("-- arrange --"); if (!bt_sink_bin_is_record_format_supported (_i)) return; // see GST_BUG_733031 if (_i == 3 || _i == 6) return; #if !GST_CHECK_VERSION (1,8,0) if (_i == 5 || _i == 7) return; #endif make_new_song ( /*silence */ 4); GstElement *sink_bin = get_sink_bin (); GEnumClass *enum_class = g_type_class_peek_static (BT_TYPE_SINK_BIN_RECORD_FORMAT); GEnumValue *enum_value = g_enum_get_value (enum_class, _i); gchar *filename = make_tmp_song_path ("record", enum_value->value_name); g_object_set (sink_bin, "mode", BT_SINK_BIN_MODE_RECORD, "record-format", _i, "record-file-name", filename, NULL); GST_INFO ("-- act --"); GST_INFO ("act: == %s ==", filename); bt_song_play (song); run_main_loop_until_eos (); bt_song_stop (song); g_object_set (sink_bin, "mode", BT_SINK_BIN_MODE_PLAY, NULL); GST_INFO ("-- assert --"); GST_INFO ("assert: == %s ==", filename); fail_unless (g_file_test (filename, G_FILE_TEST_IS_REGULAR)); GStatBuf st; g_stat (filename, &st); ck_assert_int_gt (st.st_size, 0); ck_assert_str_eq_and_free (get_media_type (filename), media_types[_i]); GST_INFO ("-- cleanup --"); g_free (filename); gst_object_unref (sink_bin); BT_TEST_END; }
static void bt_edit_application_dispose (GObject * object) { BtEditApplication *self = BT_EDIT_APPLICATION (object); return_if_disposed (); self->priv->dispose_has_run = TRUE; /* This should destroy the window as this is a child of the app. * Problem 1: On the other hand, this *NEVER* gets called as long as the window keeps its * strong reference to the app. * Solution 1: Only use weak refs when reffing upstream objects */ GST_DEBUG ("!!!! self=%p", self); if (self->priv->song) { GST_INFO ("song: %" G_OBJECT_REF_COUNT_FMT, G_OBJECT_LOG_REF_COUNT (self->priv->song)); bt_song_stop (self->priv->song); g_object_unref (self->priv->song); self->priv->song = NULL; } if (self->priv->main_window) { GST_INFO ("main_window: %" G_OBJECT_REF_COUNT_FMT, G_OBJECT_LOG_REF_COUNT (self->priv->main_window)); //main-menu.c::on_menu_quit_activate gtk_widget_destroy (GTK_WIDGET (self->priv->main_window)); } GST_DEBUG (" more unrefs"); g_object_try_unref (self->priv->ui_resources); g_object_try_unref (self->priv->pbc_socket); g_object_try_unref (self->priv->pbc_ic); g_object_try_unref (self->priv->ic_registry); g_object_try_unref (self->priv->change_log); g_object_try_unref (self->priv->audio_session); GST_DEBUG (" chaining up"); G_OBJECT_CLASS (bt_edit_application_parent_class)->dispose (object); GST_DEBUG (" done"); }
/* test master volume, using appsink? */ static void test_bt_sink_bin_master_volume (BT_TEST_ARGS) { BT_TEST_START; GST_INFO ("-- arrange --"); gdouble volume = 1.0 / (gdouble) _i; g_object_set (settings, "audiosink", "fakesink", NULL); make_new_song ( /*square */ 1); BtMachine *machine = bt_setup_get_machine_by_type (setup, BT_TYPE_SINK_MACHINE); GstElement *sink_bin = GST_ELEMENT (check_gobject_get_object_property (machine, "machine")); BtParameterGroup *pg = bt_machine_get_global_param_group (machine); gst_element_set_state (sink_bin, GST_STATE_READY); GstElement *fakesink = get_sink_element ((GstBin *) sink_bin); g_object_set (fakesink, "signal-handoffs", TRUE, NULL); g_signal_connect (fakesink, "preroll-handoff", (GCallback) handoff_buffer_cb, NULL); g_signal_connect (fakesink, "handoff", (GCallback) handoff_buffer_cb, NULL); GST_INFO ("-- act --"); g_object_set (sink_bin, "master-volume", volume, NULL); bt_parameter_group_set_param_default (pg, bt_parameter_group_get_param_index (pg, "master-volume")); bt_song_play (song); run_main_loop_until_eos (); GST_INFO ("-- assert --"); GST_INFO ("minv=%7.4lf, maxv=%7.4lf", minv, maxv); ck_assert_float_eq (maxv, +volume); ck_assert_float_eq (minv, -volume); GST_INFO ("-- cleanup --"); bt_song_stop (song); gst_object_unref (sink_bin); g_object_try_unref (machine); BT_TEST_END; }
/* insert analyzers */ static void test_bt_sink_bin_analyzers (BT_TEST_ARGS) { BT_TEST_START; GST_INFO ("-- arrange --"); g_object_set (settings, "audiosink", "fakesink", NULL); make_new_song ( /*square */ 1); GstElement *sink_bin = get_sink_bin (); GstElement *fakesink = gst_element_factory_make ("fakesink", NULL); GstElement *queue = gst_element_factory_make ("queue", NULL); GList *analyzers_list = g_list_prepend (g_list_prepend (NULL, fakesink), queue); g_object_set (fakesink, "signal-handoffs", TRUE, "sync", FALSE, "qos", FALSE, "silent", TRUE, "async", FALSE, NULL); g_signal_connect (fakesink, "preroll-handoff", (GCallback) handoff_buffer_cb, NULL); g_signal_connect (fakesink, "handoff", (GCallback) handoff_buffer_cb, NULL); g_object_set (queue, "max-size-buffers", 10, "max-size-bytes", 0, "max-size-time", G_GUINT64_CONSTANT (0), "leaky", 2, "silent", TRUE, NULL); g_object_set (sink_bin, "analyzers", analyzers_list, NULL); GST_INFO ("-- act --"); bt_song_play (song); run_main_loop_until_eos (); GST_INFO ("-- assert --"); GST_INFO ("minv=%7.4lf, maxv=%7.4lf", minv, maxv); ck_assert_float_eq (maxv, +1.0); ck_assert_float_eq (minv, -1.0); GST_INFO ("-- cleanup --"); bt_song_stop (song); gst_object_unref (sink_bin); BT_TEST_END; }
static gchar * client_cmd_parse_and_process (BtPlaybackControllerSocket * self, gchar * cmd) { gchar *reply = NULL; BtSong *song; g_object_get (self->priv->app, "song", &song, NULL); if (!song) return NULL; if (!strcasecmp (cmd, "browse")) { BtSongInfo *song_info = self->priv->song_info; BtSequence *sequence = self->priv->sequence; gchar *str, *temp; gulong i, length; gboolean no_labels = TRUE; g_object_get (song_info, "name", &str, NULL); g_object_get (sequence, "length", &length, NULL); reply = g_strconcat ("playlist|", str, NULL); g_free (str); if (self->priv->playlist) { g_list_free (self->priv->playlist); self->priv->playlist = NULL; } // get sequence labels for (i = 0; i < length; i++) { str = bt_sequence_get_label (sequence, i); if (str) { temp = g_strconcat (reply, "|", str, NULL); g_free (str); g_free (reply); reply = temp; no_labels = FALSE; self->priv->playlist = g_list_append (self->priv->playlist, GINT_TO_POINTER (i)); } } // if there are no labels, return the start if (no_labels) { temp = g_strconcat (reply, "|" DEFAULT_LABEL, NULL); g_free (reply); reply = temp; } } else if (!strncasecmp (cmd, "play|", 5)) { g_free (self->priv->cur_label); // always stop, so that seeking works bt_song_stop (song); // get playlst entry if (cmd[5] && self->priv->playlist) { // get position for ix-th label self->priv->cur_pos = GPOINTER_TO_INT (g_list_nth_data (self->priv->playlist, atoi (&cmd[5]))); self->priv->cur_label = bt_sequence_get_label (self->priv->sequence, self->priv->cur_pos); } else { self->priv->cur_pos = 0; self->priv->cur_label = g_strdup (DEFAULT_LABEL); } GST_INFO ("starting to play"); if (!bt_song_play (song)) { GST_WARNING ("failed to play"); } // seek - we're seeking in on_song_is_playing_notify() //GST_INFO("seeking to pos=%d",self->priv->cur_pos); // this causes stack smashing, but only if we play afterwards // its also avoided by making the string buffer in main-statusbar.c (notify) +4 bytes //g_object_set(song,"play-pos",self->priv->cur_pos,NULL); self->priv->seek = TRUE; } else if (!strcasecmp (cmd, "stop")) { if (!bt_song_stop (song)) { GST_WARNING ("failed to stop"); } } else if (!strcasecmp (cmd, "status")) { gchar *state[] = { "stopped", "playing" }; gchar *mode[] = { "on", "off" }; gulong pos, msec, sec, min; gdouble volume; gboolean loop; g_object_get (song, "play-pos", &pos, NULL); g_object_get (self->priv->sequence, "loop", &loop, NULL); // calculate playtime bt_song_info_tick_to_m_s_ms (self->priv->song_info, pos, &min, &sec, &msec); // get the current input_gain and adjust volume widget g_object_get (self->priv->gain, "volume", &volume, NULL); reply = g_strdup_printf ("event|%s|%s|0:%02lu:%02lu.%03lu|%s|%u|off|%s", state[self->priv->is_playing], self->priv->cur_label, min, sec, msec, self->priv->length_str, (guint) (100.0 * volume), mode[loop]); //reply=g_strdup("event|stopped|start|0:00:00.000|0:00:00.000|100|off|off"); } else if (!strncasecmp (cmd, "set|", 4)) { gchar *subcmd = &cmd[4]; if (!strncasecmp (subcmd, "volume|", 7)) { if (subcmd[7] && self->priv->gain) { gdouble volume; volume = ((gdouble) atoi (&subcmd[7])) / 100.0; g_object_set (self->priv->gain, "volume", volume, NULL); } } else if (!strncasecmp (subcmd, "mute|", 5)) { // we ignore this for now } else if (!strncasecmp (subcmd, "repeat|", 7)) { if (!strcasecmp (&subcmd[7], "on")) { g_object_set (self->priv->sequence, "loop", TRUE, NULL); } else if (!strcasecmp (&subcmd[7], "off")) { g_object_set (self->priv->sequence, "loop", FALSE, NULL); } } else { GST_WARNING ("unknown setting: %s", subcmd); } } else if (!strncasecmp (cmd, "get|", 4)) { gchar *subcmd = &cmd[4]; if (!strcasecmp (subcmd, "volume")) { gdouble volume; g_object_get (self->priv->gain, "volume", &volume, NULL); reply = g_strdup_printf ("volume|%u", (guint) (100.0 * volume)); } else if (!strcasecmp (subcmd, "mute")) { reply = g_strdup ("mute|off"); } else if (!strcasecmp (subcmd, "repeat")) { gboolean loop; gchar *mode[] = { "on", "off" }; g_object_get (self->priv->sequence, "loop", &loop, NULL); reply = g_strdup_printf ("repeat|%s", mode[loop]); } else { GST_WARNING ("unknown setting: %s", subcmd); } } else { GST_WARNING ("unknown command: %s", cmd); } g_object_unref (song); return reply; }