#include "Waveform.h" #include "utility.h" #include #include #include #include #include #include #include "GstMedia.h" #include "GstLaunch.h" /* * * */ /* * */ class WaveformGenerator : public GstLaunch, public Gtk::Dialog { public: WaveformGenerator(const Glib::ustring &_file, Waveform *wave, bool &result) :GstLaunch(200), Gtk::Dialog(_("Generate Waveform"), true), m_waveform(wave) { Glib::ustring file = Glib::filename_from_uri(_file); //Glib::ustring file = _file; //find_and_replace(file, "file://", ""); endtime = 0; guint interval = /*GST_MSECOND*10;*/10000000; /* gchar *pipe = g_strdup_printf( "filesrc name=src location=%s ! decodebin ! audioconvert ! level interval=%i message=true ! fakesink", file.c_str(), interval); */ /* gchar *pipe = g_strdup_printf( "filesrc name=src location=%s ! decodebin !" //"queue ! " "audioconvert !" //"audio/x-raw-int,rate=44100,channels=2 !" "level interval=%i message=true ! fakesink" , file.c_str(), interval); */ //GstElement *filesrc = gst_element_make_from_uri(GST_URI_SRC, _file.c_str(), "filesrc"); /* gchar *pipe = g_strdup_printf( "filesrc location=\"%s\" ! decodebin name=decode !" "queue max-size-buffers=500 max-size-bytes=0 max-size-time=0 ! audioconvert ! " "level interval=%i message=true ! fakesink" , file.c_str(), interval); */ gchar *pipe = g_strdup_printf( "filesrc name=filesrc ! decodebin name=decode !" "queue max-size-buffers=500 max-size-bytes=0 max-size-time=0 ! audioconvert ! " "level interval=%i message=true ! fakesink" , interval); bool res = parse(pipe); g_free(pipe); if(res) { GstElement *filesrc = gst_bin_get_by_name(GST_BIN(m_pipeline), "filesrc"); gst_uri_handler_set_uri(GST_URI_HANDLER(filesrc), _file.c_str()); ready(); createProgressBar(); play(); sigc::connection id = get_signal_timeout().connect( sigc::mem_fun(*this, &WaveformGenerator::on_update_progressbar)); if( run() == Gtk::RESPONSE_OK) result = true; else result = false; id.disconnect(); } else { std::cerr << "WaveformGenerator > parse failed" << std::endl; //throw Glib::Error("Parse Failed"); throw "parse failed"; } } ~WaveformGenerator() { } bool bus_message(GstBus *bus, GstMessage *message) throw (GstLaunch::Error) { bool state = GstLaunch::bus_message(bus, message); if(message->type == GST_MESSAGE_EOS) { response(Gtk::RESPONSE_OK); //m_mainloop->quit(); } else if(message->type == GST_MESSAGE_ELEMENT) { const GstStructure* structure = gst_message_get_structure(message); const gchar* name = gst_structure_get_name(structure); if(strcmp(name, "level") == 0) { gst_structure_get_clock_time (structure, "endtime", &endtime); const GValue* list = NULL; const GValue* value = NULL; list = gst_structure_get_value (structure, "rms"); m_waveform->n_channels = gst_value_list_get_size (list); if(m_waveform->n_channels > 2) m_waveform->n_channels = 2; for(unsigned int i=0; i< m_waveform->n_channels; ++i) { gdouble rms_dB, peak_dB, decay_dB; gdouble rms; list = gst_structure_get_value (structure, "rms"); value = gst_value_list_get_value (list, i); rms_dB = g_value_get_double (value); list = gst_structure_get_value (structure, "peak"); value = gst_value_list_get_value (list, i); peak_dB = g_value_get_double (value); list = gst_structure_get_value (structure, "decay"); value = gst_value_list_get_value (list, i); decay_dB = g_value_get_double (value); rms = pow (10, rms_dB / 20); // TODO fixme! m_waveform->channels[i].push_back(rms); } // TODO fixme! if(m_waveform->len == 0) { m_waveform->len = get_duration(); } } } return state; } void on_eos() { } void on_error() { Gtk::MessageDialog err(_("Error Generate waveform"), false, Gtk::MESSAGE_ERROR); err.run(); response(Gtk::RESPONSE_CANCEL); } void createProgressBar() { set_border_width(6); set_default_size(300,-1); get_vbox()->pack_start(m_progressbar, false,false); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL)->signal_clicked().connect( sigc::mem_fun(*this, &WaveformGenerator::on_cancel)); show_all(); } void on_update_progressbar() { gint64 pos = endtime; double percent = ((double)pos / (double)get_duration()); if(percent < 0) percent = 0; else if(percent > 1) percent = 1; m_progressbar.set_fraction(percent); m_progressbar.set_text((Gst::time_to_string(pos) + " / " + Gst::time_to_string(get_duration()))); } void on_cancel() { null(); } protected: Waveform* m_waveform; Glib::RefPtr m_mainloop; Gtk::ProgressBar m_progressbar; GstClockTime endtime; }; /* * */ bool generate_waveform(const Glib::ustring &uri, Waveform **waveform) { try { bool result = false; Waveform *wf = new Waveform; // // is waveform file ? std::cout << "open " << uri << std::endl; if(wf->open(uri)) { std::cout << "use waveform file" << std::endl; *waveform = wf; return true; } else { delete wf; wf = new Waveform; } // WaveformGenerator(uri, wf, result); if(result) { *waveform = wf; wf->uri = uri; return true; } else if(wf) delete wf; return false; } catch(...) { } return false; }