mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-17 20:26:30 +01:00
Further Freesound import tweaks.
Make download of sound files multi-threaded. Each sound file download takes place in its own thread, and has its own progress bar and cancel button, which stack up from the bottom of the list of results. Sound files download into a file with a '.part' suffix, which is then renamed to the intended name on success. Add a 'Similar' button, which searches Freesound for sounds similar to the currently-selected sound in the results list. Add a freesound-download-dir config variable to decide the location of sound files downloaded from Freesound. Move Windows-specific logic to replace '/'s with '\'s from Mootcher::changeWorkingDir() to Mootcher::ensureWorkingDir(), and remove the now unused Mootcher::changeWorkingDir(). Use Glib::build_filename to construct paths.
This commit is contained in:
commit
9a9f4276a0
5 changed files with 301 additions and 175 deletions
|
|
@ -53,6 +53,9 @@
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
#include "ardour/audio_library.h"
|
#include "ardour/audio_library.h"
|
||||||
|
#include "ardour/rc_configuration.h"
|
||||||
|
#include "pbd/pthread_utils.h"
|
||||||
|
#include "gui_thread.h"
|
||||||
|
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
|
|
@ -63,9 +66,12 @@ static const std::string api_key = "9d77cb8d841b4bcfa960e1aae62224eb"; // ardour
|
||||||
Mootcher::Mootcher()
|
Mootcher::Mootcher()
|
||||||
: curl(curl_easy_init())
|
: curl(curl_easy_init())
|
||||||
{
|
{
|
||||||
std::string path;
|
cancel_download_btn.set_label (_("Cancel"));
|
||||||
path = Glib::get_home_dir() + "/Freesound/";
|
progress_hbox.pack_start (progress_bar, true, true);
|
||||||
changeWorkingDir ( path.c_str() );
|
progress_hbox.pack_end (cancel_download_btn, false, false);
|
||||||
|
progress_bar.show();
|
||||||
|
cancel_download_btn.show();
|
||||||
|
cancel_download_btn.signal_clicked().connect(sigc::mem_fun (*this, &Mootcher::cancelDownload));
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
Mootcher:: ~Mootcher()
|
Mootcher:: ~Mootcher()
|
||||||
|
|
@ -74,9 +80,17 @@ Mootcher:: ~Mootcher()
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
void Mootcher::changeWorkingDir(const char *saveLocation)
|
|
||||||
|
void Mootcher::ensureWorkingDir ()
|
||||||
{
|
{
|
||||||
basePath = saveLocation;
|
std::string p = ARDOUR::Config->get_freesound_download_dir();
|
||||||
|
|
||||||
|
if (!Glib::file_test (p, Glib::FILE_TEST_IS_DIR)) {
|
||||||
|
if (g_mkdir_with_parents (p.c_str(), 0775) != 0) {
|
||||||
|
PBD::error << "Unable to create Mootcher working dir" << endmsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
basePath = p;
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
std::string replace = "/";
|
std::string replace = "/";
|
||||||
size_t pos = basePath.find("\\");
|
size_t pos = basePath.find("\\");
|
||||||
|
|
@ -85,20 +99,6 @@ void Mootcher::changeWorkingDir(const char *saveLocation)
|
||||||
pos = basePath.find("\\");
|
pos = basePath.find("\\");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//
|
|
||||||
size_t pos2 = basePath.find_last_of("/");
|
|
||||||
if(basePath.length() != (pos2+1)) basePath += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mootcher::ensureWorkingDir ()
|
|
||||||
{
|
|
||||||
std::string p = Glib::build_filename (basePath, "snd");
|
|
||||||
|
|
||||||
if (!Glib::file_test (p, Glib::FILE_TEST_IS_DIR)) {
|
|
||||||
if (g_mkdir_with_parents (p.c_str(), 0775) != 0) {
|
|
||||||
PBD::error << "Unable to create Mootcher working dir" << endmsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -121,7 +121,8 @@ size_t Mootcher::WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
std::string Mootcher::sortMethodString(enum sortMethod sort) {
|
std::string Mootcher::sortMethodString(enum sortMethod sort)
|
||||||
|
{
|
||||||
// given a sort type, returns the string value to be passed to the API to
|
// given a sort type, returns the string value to be passed to the API to
|
||||||
// sort the results in the requested way.
|
// sort the results in the requested way.
|
||||||
|
|
||||||
|
|
@ -202,6 +203,18 @@ std::string Mootcher::doRequest(std::string uri, std::string params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Mootcher::searchSimilar(std::string id)
|
||||||
|
{
|
||||||
|
std::string params = "";
|
||||||
|
|
||||||
|
params += "&fields=id,original_filename,duration,filesize,samplerate,license,serve";
|
||||||
|
params += "&num_results=100";
|
||||||
|
|
||||||
|
return doRequest("/sounds/" + id + "/similar", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
std::string Mootcher::searchText(std::string query, int page, std::string filter, enum sortMethod sort)
|
std::string Mootcher::searchText(std::string query, int page, std::string filter, enum sortMethod sort)
|
||||||
{
|
{
|
||||||
std::string params = "";
|
std::string params = "";
|
||||||
|
|
@ -264,7 +277,7 @@ std::string Mootcher::getSoundResourceFile(std::string ID)
|
||||||
// get the file name and size from xml file
|
// get the file name and size from xml file
|
||||||
if (name) {
|
if (name) {
|
||||||
|
|
||||||
audioFileName = basePath + "snd/" + ID + "-" + name->child("text")->content();
|
audioFileName = Glib::build_filename (basePath, ID + "-" + name->child("text")->content());
|
||||||
|
|
||||||
//store all the tags in the database
|
//store all the tags in the database
|
||||||
XMLNode *tags = freesound->child("tags");
|
XMLNode *tags = freesound->child("tags");
|
||||||
|
|
@ -296,10 +309,61 @@ int audioFileWrite(void *buffer, size_t size, size_t nmemb, void *file)
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID, std::string audioURL, SoundFileBrowser *caller)
|
|
||||||
|
void *
|
||||||
|
Mootcher::threadFunc() {
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
res = curl_easy_perform (curl);
|
||||||
|
fclose (theFile);
|
||||||
|
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); // turn off the progress bar
|
||||||
|
|
||||||
|
if (res != CURLE_OK) {
|
||||||
|
/* it's not an error if the user pressed the stop button */
|
||||||
|
if (res != CURLE_ABORTED_BY_CALLBACK) {
|
||||||
|
error << string_compose (_("curl error %1 (%2)"), res, curl_easy_strerror(res)) << endmsg;
|
||||||
|
}
|
||||||
|
remove ( (audioFileName+".part").c_str() );
|
||||||
|
} else {
|
||||||
|
rename ( (audioFileName+".part").c_str(), audioFileName.c_str() );
|
||||||
|
// now download the tags &c.
|
||||||
|
getSoundResourceFile(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *) res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mootcher::doneWithMootcher()
|
||||||
|
{
|
||||||
|
|
||||||
|
// update the sound info pane if the selection in the list box is still us
|
||||||
|
sfb->refresh_display(ID, audioFileName);
|
||||||
|
|
||||||
|
delete this; // this should be OK to do as long as Progress and Finished signals are always received in the order in which they are emitted
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
freesound_download_thread_func(void *arg)
|
||||||
|
{
|
||||||
|
Mootcher *thisMootcher = (Mootcher *) arg;
|
||||||
|
void *res;
|
||||||
|
|
||||||
|
// std::cerr << "freesound_download_thread_func(" << arg << ")" << std::endl;
|
||||||
|
res = thisMootcher->threadFunc();
|
||||||
|
|
||||||
|
thisMootcher->Finished(); /* EMIT SIGNAL */
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool Mootcher::checkAudioFile(std::string originalFileName, std::string theID)
|
||||||
{
|
{
|
||||||
ensureWorkingDir();
|
ensureWorkingDir();
|
||||||
std::string audioFileName = basePath + "snd/" + ID + "-" + originalFileName;
|
ID = theID;
|
||||||
|
audioFileName = Glib::build_filename (basePath, ID + "-" + originalFileName);
|
||||||
|
|
||||||
// check to see if audio file already exists
|
// check to see if audio file already exists
|
||||||
FILE *testFile = g_fopen(audioFileName.c_str(), "r");
|
FILE *testFile = g_fopen(audioFileName.c_str(), "r");
|
||||||
|
|
@ -307,29 +371,31 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
|
||||||
fseek (testFile , 0 , SEEK_END);
|
fseek (testFile , 0 , SEEK_END);
|
||||||
if (ftell (testFile) > 256) {
|
if (ftell (testFile) > 256) {
|
||||||
fclose (testFile);
|
fclose (testFile);
|
||||||
return audioFileName;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// else file was small, probably an error, delete it and try again
|
// else file was small, probably an error, delete it
|
||||||
fclose(testFile);
|
fclose(testFile);
|
||||||
remove( audioFileName.c_str() );
|
remove( audioFileName.c_str() );
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Mootcher::fetchAudioFile(std::string originalFileName, std::string theID, std::string audioURL, SoundFileBrowser *caller)
|
||||||
|
{
|
||||||
|
ensureWorkingDir();
|
||||||
|
ID = theID;
|
||||||
|
audioFileName = Glib::build_filename (basePath, ID + "-" + originalFileName);
|
||||||
|
|
||||||
if (!curl) {
|
if (!curl) {
|
||||||
return "";
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if already cancelling a previous download, bail out here ( this can happen b/c getAudioFile gets called by various UI update funcs )
|
|
||||||
if ( caller->freesound_download_cancel ) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// now download the actual file
|
// now download the actual file
|
||||||
FILE* theFile;
|
theFile = g_fopen( (audioFileName + ".part").c_str(), "wb" );
|
||||||
theFile = g_fopen( audioFileName.c_str(), "wb" );
|
|
||||||
|
|
||||||
if (!theFile) {
|
if (!theFile) {
|
||||||
return "";
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the download url
|
// create the download url
|
||||||
|
|
@ -340,57 +406,59 @@ std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID,
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, audioFileWrite);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, audioFileWrite);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, theFile);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, theFile);
|
||||||
|
|
||||||
/* hack to get rid of the barber-pole stripes */
|
|
||||||
caller->freesound_progress_bar.hide();
|
|
||||||
caller->freesound_progress_bar.show();
|
|
||||||
|
|
||||||
std::string prog;
|
std::string prog;
|
||||||
prog = string_compose (_("%1"), originalFileName);
|
prog = string_compose (_("%1"), originalFileName);
|
||||||
caller->freesound_progress_bar.set_text(prog);
|
progress_bar.set_text(prog);
|
||||||
|
|
||||||
|
Gtk::VBox *freesound_vbox = dynamic_cast<Gtk::VBox *> (caller->notebook.get_nth_page(2));
|
||||||
|
freesound_vbox->pack_start(progress_hbox, Gtk::PACK_SHRINK);
|
||||||
|
progress_hbox.show();
|
||||||
|
cancel_download = false;
|
||||||
|
sfb = caller;
|
||||||
|
|
||||||
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); // turn on the progress bar
|
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); // turn on the progress bar
|
||||||
curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
|
curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
|
||||||
curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, caller);
|
curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, this);
|
||||||
|
|
||||||
CURLcode res = curl_easy_perform(curl);
|
Progress.connect(*this, invalidator (*this), boost::bind(&Mootcher::updateProgress, this, _1, _2), gui_context());
|
||||||
fclose(theFile);
|
Finished.connect(*this, invalidator (*this), boost::bind(&Mootcher::doneWithMootcher, this), gui_context());
|
||||||
|
pthread_t freesound_download_thread;
|
||||||
|
pthread_create_and_store("freesound_import", &freesound_download_thread, freesound_download_thread_func, this);
|
||||||
|
|
||||||
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); // turn off the progress bar
|
return true;
|
||||||
caller->freesound_progress_bar.set_fraction(0.0);
|
|
||||||
caller->freesound_progress_bar.set_text("");
|
|
||||||
|
|
||||||
if( res != 0 ) {
|
|
||||||
/* it's not an error if the user pressed the stop button */
|
|
||||||
if (res != CURLE_ABORTED_BY_CALLBACK) {
|
|
||||||
error << string_compose (_("curl error %1 (%2)"), res, curl_easy_strerror(res)) << endmsg;
|
|
||||||
}
|
|
||||||
remove( audioFileName.c_str() );
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
// now download the tags &c.
|
|
||||||
getSoundResourceFile(ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return audioFileName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
int Mootcher::progress_callback(void *caller, double dltotal, double dlnow, double /*ultotal*/, double /*ulnow*/)
|
|
||||||
{
|
|
||||||
|
|
||||||
SoundFileBrowser *sfb = (SoundFileBrowser *) caller;
|
void
|
||||||
//XXX I hope it's OK to do GTK things in this callback. Otherwise
|
Mootcher::updateProgress(double dlnow, double dltotal)
|
||||||
// I'll have to do stuff like in interthread_progress_window.
|
{
|
||||||
if (sfb->freesound_download_cancel) {
|
if (dltotal > 0) {
|
||||||
|
double fraction = dlnow / dltotal;
|
||||||
|
// std::cerr << "progress idle: " << progress->bar->get_text() << ". " << progress->dlnow << " / " << progress->dltotal << " = " << fraction << std::endl;
|
||||||
|
if (fraction > 1.0) {
|
||||||
|
fraction = 1.0;
|
||||||
|
} else if (fraction < 0.0) {
|
||||||
|
fraction = 0.0;
|
||||||
|
}
|
||||||
|
progress_bar.set_fraction(fraction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Mootcher::progress_callback(void *caller, double dltotal, double dlnow, double /*ultotal*/, double /*ulnow*/)
|
||||||
|
{
|
||||||
|
// It may seem curious to pass a pointer to an instance of an object to a static
|
||||||
|
// member function, but we can't use a normal member function as a curl progress callback,
|
||||||
|
// and we want access to some private members of Mootcher.
|
||||||
|
|
||||||
|
Mootcher *thisMootcher = (Mootcher *) caller;
|
||||||
|
|
||||||
|
if (thisMootcher->cancel_download) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thisMootcher->Progress(dlnow, dltotal); /* EMIT SIGNAL */
|
||||||
sfb->freesound_progress_bar.set_fraction(dlnow/dltotal);
|
|
||||||
/* Make sure the progress widget gets updated */
|
|
||||||
while (Glib::MainContext::get_default()->iteration (false)) {
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,18 +65,31 @@ enum sortMethod {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Mootcher
|
class Mootcher: public sigc::trackable, public PBD::ScopedConnectionList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Mootcher();
|
Mootcher();
|
||||||
~Mootcher();
|
~Mootcher();
|
||||||
|
|
||||||
std::string getAudioFile(std::string originalFileName, std::string ID, std::string audioURL, SoundFileBrowser *caller);
|
bool checkAudioFile(std::string originalFileName, std::string ID);
|
||||||
|
bool fetchAudioFile(std::string originalFileName, std::string ID, std::string audioURL, SoundFileBrowser *caller);
|
||||||
std::string searchText(std::string query, int page, std::string filter, enum sortMethod sort);
|
std::string searchText(std::string query, int page, std::string filter, enum sortMethod sort);
|
||||||
|
std::string searchSimilar(std::string id);
|
||||||
|
void * threadFunc();
|
||||||
|
SoundFileBrowser *sfb;
|
||||||
|
std::string audioFileName;
|
||||||
|
std::string ID;
|
||||||
|
|
||||||
|
/** signal emitted when mootcher reports progress updates during download.
|
||||||
|
* The parameters are current and total numbers of bytes downloaded.
|
||||||
|
*/
|
||||||
|
PBD::Signal2<void, double, double> Progress;
|
||||||
|
/** signal emitted when the mootcher has finished downloading. */
|
||||||
|
PBD::Signal0<void> Finished;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void changeWorkingDir(const char *saveLocation);
|
|
||||||
void ensureWorkingDir();
|
void ensureWorkingDir();
|
||||||
|
|
||||||
std::string doRequest(std::string uri, std::string params);
|
std::string doRequest(std::string uri, std::string params);
|
||||||
|
|
@ -90,6 +103,21 @@ private:
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
char errorBuffer[CURL_ERROR_SIZE]; // storage for cUrl error message
|
char errorBuffer[CURL_ERROR_SIZE]; // storage for cUrl error message
|
||||||
|
|
||||||
|
FILE* theFile;
|
||||||
|
|
||||||
|
void updateProgress(double dlnow, double dltotal);
|
||||||
|
void doneWithMootcher();
|
||||||
|
|
||||||
|
Gtk::HBox progress_hbox;
|
||||||
|
Gtk::ProgressBar progress_bar;
|
||||||
|
Gtk::Button cancel_download_btn;
|
||||||
|
|
||||||
|
bool cancel_download;
|
||||||
|
void cancelDownload() {
|
||||||
|
cancel_download = true;
|
||||||
|
progress_hbox.hide();
|
||||||
|
}
|
||||||
|
|
||||||
std::string basePath;
|
std::string basePath;
|
||||||
std::string xmlLocation;
|
std::string xmlLocation;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ using namespace Editing;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
string SoundFileBrowser::persistent_folder;
|
string SoundFileBrowser::persistent_folder;
|
||||||
|
typedef TreeView::Selection::ListHandle_Path ListPath;
|
||||||
|
|
||||||
static ImportMode
|
static ImportMode
|
||||||
string2importmode (string str)
|
string2importmode (string str)
|
||||||
|
|
@ -512,8 +513,6 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persi
|
||||||
found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
|
found_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
|
||||||
found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
|
found_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::found_search_clicked));
|
||||||
|
|
||||||
freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
|
|
||||||
|
|
||||||
notebook.append_page (*vbox, _("Search Tags"));
|
notebook.append_page (*vbox, _("Search Tags"));
|
||||||
|
|
||||||
#ifdef FREESOUND
|
#ifdef FREESOUND
|
||||||
|
|
@ -555,9 +554,9 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persi
|
||||||
freesound_more_btn.set_label(_("More"));
|
freesound_more_btn.set_label(_("More"));
|
||||||
freesound_more_btn.set_sensitive(false);
|
freesound_more_btn.set_sensitive(false);
|
||||||
|
|
||||||
passbox->pack_end (freesound_stop_btn, false, false);
|
passbox->pack_start (freesound_similar_btn, false, false);
|
||||||
freesound_stop_btn.set_label(_("Stop"));
|
freesound_similar_btn.set_label(_("Similar"));
|
||||||
freesound_stop_btn.set_sensitive(false);
|
freesound_similar_btn.set_sensitive(false);
|
||||||
|
|
||||||
scroll = manage(new ScrolledWindow);
|
scroll = manage(new ScrolledWindow);
|
||||||
scroll->add(freesound_list_view);
|
scroll->add(freesound_list_view);
|
||||||
|
|
@ -566,9 +565,8 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persi
|
||||||
vbox = manage(new VBox);
|
vbox = manage(new VBox);
|
||||||
vbox->set_spacing (3);
|
vbox->set_spacing (3);
|
||||||
vbox->pack_start (*passbox, PACK_SHRINK);
|
vbox->pack_start (*passbox, PACK_SHRINK);
|
||||||
vbox->pack_start (freesound_progress_bar, PACK_SHRINK);
|
|
||||||
vbox->pack_start (*scroll);
|
vbox->pack_start (*scroll);
|
||||||
|
|
||||||
freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
|
freesound_list_view.append_column(_("ID") , freesound_list_columns.id);
|
||||||
freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
|
freesound_list_view.append_column(_("Filename"), freesound_list_columns.filename);
|
||||||
// freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
|
// freesound_list_view.append_column(_("URI") , freesound_list_columns.uri);
|
||||||
|
|
@ -577,20 +575,22 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s, bool persi
|
||||||
freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
|
freesound_list_view.append_column(_("Samplerate"), freesound_list_columns.smplrate);
|
||||||
freesound_list_view.append_column(_("License"), freesound_list_columns.license);
|
freesound_list_view.append_column(_("License"), freesound_list_columns.license);
|
||||||
freesound_list_view.get_column(0)->set_alignment(0.5);
|
freesound_list_view.get_column(0)->set_alignment(0.5);
|
||||||
freesound_list_view.get_column(1)->set_expand(true);
|
freesound_list_view.get_column(1)->set_expand(true); // filename
|
||||||
|
freesound_list_view.get_column(1)->set_resizable(true); // filename
|
||||||
freesound_list_view.get_column(2)->set_alignment(0.5);
|
freesound_list_view.get_column(2)->set_alignment(0.5);
|
||||||
freesound_list_view.get_column(3)->set_alignment(0.5);
|
freesound_list_view.get_column(3)->set_alignment(0.5);
|
||||||
freesound_list_view.get_column(4)->set_alignment(0.5);
|
freesound_list_view.get_column(4)->set_alignment(0.5);
|
||||||
freesound_list_view.get_column(5)->set_alignment(0.5);
|
freesound_list_view.get_column(5)->set_alignment(0.5);
|
||||||
|
|
||||||
freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
|
freesound_list_view.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_list_view_selected));
|
||||||
|
freesound_list_view.set_tooltip_column(1);
|
||||||
|
|
||||||
freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
|
freesound_list_view.get_selection()->set_mode (SELECTION_MULTIPLE);
|
||||||
freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
|
freesound_list_view.signal_row_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::freesound_list_view_activated));
|
||||||
freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
|
freesound_search_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
|
||||||
freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
|
freesound_entry.signal_activate().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_search_clicked));
|
||||||
freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
|
freesound_more_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_more_clicked));
|
||||||
freesound_stop_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_stop_clicked));
|
freesound_similar_btn.signal_clicked().connect(sigc::mem_fun(*this, &SoundFileBrowser::freesound_similar_clicked));
|
||||||
notebook.append_page (*vbox, _("Search Freesound"));
|
notebook.append_page (*vbox, _("Search Freesound"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -787,7 +787,7 @@ SoundFileBrowser::found_list_view_selected ()
|
||||||
} else {
|
} else {
|
||||||
string file;
|
string file;
|
||||||
|
|
||||||
TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows ();
|
ListPath rows = found_list_view.get_selection()->get_selected_rows ();
|
||||||
|
|
||||||
if (!rows.empty()) {
|
if (!rows.empty()) {
|
||||||
TreeIter iter = found_list->get_iter(*rows.begin());
|
TreeIter iter = found_list->get_iter(*rows.begin());
|
||||||
|
|
@ -802,55 +802,6 @@ SoundFileBrowser::found_list_view_selected ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SoundFileBrowser::freesound_list_view_selected ()
|
|
||||||
{
|
|
||||||
freesound_download_cancel = false;
|
|
||||||
freesound_stop_btn.set_sensitive(true);
|
|
||||||
|
|
||||||
#ifdef FREESOUND
|
|
||||||
if (!reset_options ()) {
|
|
||||||
set_action_sensitive (false);
|
|
||||||
} else {
|
|
||||||
Mootcher mootcher;
|
|
||||||
string file;
|
|
||||||
|
|
||||||
TreeView::Selection::ListHandle_Path rows = freesound_list_view.get_selection()->get_selected_rows ();
|
|
||||||
|
|
||||||
if (!rows.empty()) {
|
|
||||||
TreeIter iter = freesound_list->get_iter(*rows.begin());
|
|
||||||
|
|
||||||
string id = (*iter)[freesound_list_columns.id];
|
|
||||||
string uri = (*iter)[freesound_list_columns.uri];
|
|
||||||
string ofn = (*iter)[freesound_list_columns.filename];
|
|
||||||
|
|
||||||
// download the sound file
|
|
||||||
GdkCursor *prev_cursor;
|
|
||||||
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
|
||||||
gdk_flush();
|
|
||||||
|
|
||||||
file = mootcher.getAudioFile(ofn, id, uri, this);
|
|
||||||
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
|
||||||
|
|
||||||
if (file != "") {
|
|
||||||
chooser.set_filename (file);
|
|
||||||
set_action_sensitive (true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
set_action_sensitive (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
freesound_progress_bar.set_text(
|
|
||||||
string_compose(P_("found %1 match", "found %1 matches", matches), matches));
|
|
||||||
|
|
||||||
preview.setup_labels (file);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
freesound_stop_btn.set_sensitive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SoundFileBrowser::found_search_clicked ()
|
SoundFileBrowser::found_search_clicked ()
|
||||||
{
|
{
|
||||||
|
|
@ -875,6 +826,91 @@ SoundFileBrowser::found_search_clicked ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
|
||||||
|
{
|
||||||
|
|
||||||
|
Mootcher *mootcher = new Mootcher;
|
||||||
|
std::string file;
|
||||||
|
|
||||||
|
string id = (*iter)[freesound_list_columns.id];
|
||||||
|
string uri = (*iter)[freesound_list_columns.uri];
|
||||||
|
string ofn = (*iter)[freesound_list_columns.filename];
|
||||||
|
|
||||||
|
if (mootcher->checkAudioFile(ofn, id)) {
|
||||||
|
// file already exists, no need to download it again
|
||||||
|
file = mootcher->audioFileName;
|
||||||
|
delete mootcher;
|
||||||
|
(*iter)[freesound_list_columns.started] = false;
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
if (!(*iter)[freesound_list_columns.started]) {
|
||||||
|
// start downloading the sound file
|
||||||
|
(*iter)[freesound_list_columns.started] = true;
|
||||||
|
mootcher->fetchAudioFile(ofn, id, uri, this);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SoundFileBrowser::freesound_list_view_selected ()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!reset_options ()) {
|
||||||
|
set_action_sensitive (false);
|
||||||
|
} else {
|
||||||
|
std::string file;
|
||||||
|
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
||||||
|
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
||||||
|
file = freesound_get_audio_file (freesound_list->get_iter(*i));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rows.size()) {
|
||||||
|
case 0:
|
||||||
|
// nothing selected
|
||||||
|
freesound_similar_btn.set_sensitive(false);
|
||||||
|
set_action_sensitive (false);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// exactly one item selected
|
||||||
|
if (file != "") {
|
||||||
|
// file exists on disk already
|
||||||
|
chooser.set_filename (file);
|
||||||
|
preview.setup_labels (file);
|
||||||
|
set_action_sensitive (true);
|
||||||
|
}
|
||||||
|
freesound_similar_btn.set_sensitive(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// multiple items selected
|
||||||
|
preview.setup_labels ("");
|
||||||
|
freesound_similar_btn.set_sensitive(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SoundFileBrowser::refresh_display(std::string ID, std::string file)
|
||||||
|
{
|
||||||
|
// called when the mootcher has finished downloading a file
|
||||||
|
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
||||||
|
if (rows.size() == 1) {
|
||||||
|
// there's a single item selected in the freesound list
|
||||||
|
//XXX make a function to be used to construct the actual file name both here and in the mootcher
|
||||||
|
Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
|
||||||
|
std::string selected_ID = (*row)[freesound_list_columns.id];
|
||||||
|
if (ID == selected_ID) {
|
||||||
|
// the selected item in the freesound list is the item that has just finished downloading
|
||||||
|
chooser.set_filename(file);
|
||||||
|
preview.setup_labels (file);
|
||||||
|
set_action_sensitive (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_search_clicked ()
|
SoundFileBrowser::freesound_search_clicked ()
|
||||||
{
|
{
|
||||||
|
|
@ -895,18 +931,32 @@ SoundFileBrowser::freesound_more_clicked ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_stop_clicked ()
|
SoundFileBrowser::freesound_similar_clicked ()
|
||||||
{
|
{
|
||||||
freesound_download_cancel = true;
|
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
||||||
}
|
if (rows.size() == 1) {
|
||||||
|
Mootcher mootcher;
|
||||||
|
string id;
|
||||||
|
Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
|
||||||
|
id = (*iter)[freesound_list_columns.id];
|
||||||
|
freesound_list->clear();
|
||||||
|
|
||||||
|
GdkCursor *prev_cursor;
|
||||||
|
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
||||||
|
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
||||||
|
gdk_flush();
|
||||||
|
|
||||||
|
std::string theString = mootcher.searchSimilar(id);
|
||||||
|
|
||||||
|
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
||||||
|
handle_freesound_results(theString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SoundFileBrowser::freesound_search()
|
SoundFileBrowser::freesound_search()
|
||||||
{
|
{
|
||||||
#ifdef FREESOUND
|
|
||||||
Mootcher mootcher;
|
Mootcher mootcher;
|
||||||
freesound_list_view.get_column(1)->set_sizing(TREE_VIEW_COLUMN_GROW_ONLY);
|
|
||||||
|
|
||||||
string search_string = freesound_entry.get_text ();
|
string search_string = freesound_entry.get_text ();
|
||||||
enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
|
enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
|
||||||
|
|
@ -914,7 +964,6 @@ SoundFileBrowser::freesound_search()
|
||||||
GdkCursor *prev_cursor;
|
GdkCursor *prev_cursor;
|
||||||
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
||||||
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
||||||
freesound_progress_bar.set_fraction(0.0);
|
|
||||||
gdk_flush();
|
gdk_flush();
|
||||||
|
|
||||||
std::string theString = mootcher.searchText(
|
std::string theString = mootcher.searchText(
|
||||||
|
|
@ -929,7 +978,11 @@ SoundFileBrowser::freesound_search()
|
||||||
);
|
);
|
||||||
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
||||||
|
handle_freesound_results(theString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SoundFileBrowser::handle_freesound_results(std::string theString) {
|
||||||
XMLTree doc;
|
XMLTree doc;
|
||||||
doc.read_buffer( theString );
|
doc.read_buffer( theString );
|
||||||
XMLNode *root = doc.root();
|
XMLNode *root = doc.root();
|
||||||
|
|
@ -1065,14 +1118,6 @@ SoundFileBrowser::freesound_search()
|
||||||
matches++;
|
matches++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches == 0) {
|
|
||||||
freesound_progress_bar.set_text(_("Search returned no results."));
|
|
||||||
} else {
|
|
||||||
freesound_progress_bar.set_text(string_compose(P_("Found %1 match", "Found %1 matches", matches), matches));
|
|
||||||
}
|
|
||||||
freesound_list_view.get_column(1)->set_sizing(TREE_VIEW_COLUMN_AUTOSIZE);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string>
|
vector<string>
|
||||||
|
|
@ -1093,9 +1138,7 @@ SoundFileBrowser::get_paths ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (n==1){
|
} else if (n == 1) {
|
||||||
|
|
||||||
typedef TreeView::Selection::ListHandle_Path ListPath;
|
|
||||||
|
|
||||||
ListPath rows = found_list_view.get_selection()->get_selected_rows ();
|
ListPath rows = found_list_view.get_selection()->get_selected_rows ();
|
||||||
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
||||||
|
|
@ -1106,28 +1149,12 @@ SoundFileBrowser::get_paths ()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef FREESOUND
|
#ifdef FREESOUND
|
||||||
typedef TreeView::Selection::ListHandle_Path ListPath;
|
|
||||||
Mootcher mootcher;
|
|
||||||
|
|
||||||
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
|
||||||
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
|
||||||
TreeIter iter = freesound_list->get_iter(*i);
|
string str = freesound_get_audio_file (freesound_list->get_iter(*i));
|
||||||
string id = (*iter)[freesound_list_columns.id];
|
|
||||||
string uri = (*iter)[freesound_list_columns.uri];
|
|
||||||
string ofn = (*iter)[freesound_list_columns.filename];
|
|
||||||
|
|
||||||
GdkCursor *prev_cursor;
|
|
||||||
prev_cursor = gdk_window_get_cursor (get_window()->gobj());
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
|
|
||||||
gdk_flush();
|
|
||||||
|
|
||||||
string str = mootcher.getAudioFile(ofn, id, uri, this);
|
|
||||||
if (str != "") {
|
if (str != "") {
|
||||||
results.push_back (str);
|
results.push_back (str);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
Gtk::TreeModelColumn<std::string> filesize;
|
Gtk::TreeModelColumn<std::string> filesize;
|
||||||
Gtk::TreeModelColumn<std::string> smplrate;
|
Gtk::TreeModelColumn<std::string> smplrate;
|
||||||
Gtk::TreeModelColumn<std::string> license;
|
Gtk::TreeModelColumn<std::string> license;
|
||||||
|
Gtk::TreeModelColumn<bool> started;
|
||||||
|
|
||||||
FreesoundColumns() {
|
FreesoundColumns() {
|
||||||
add(id);
|
add(id);
|
||||||
|
|
@ -140,6 +141,7 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
add(filesize);
|
add(filesize);
|
||||||
add(smplrate);
|
add(smplrate);
|
||||||
add(license);
|
add(license);
|
||||||
|
add(started);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -150,8 +152,9 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
Glib::RefPtr<Gtk::ListStore> freesound_list;
|
Glib::RefPtr<Gtk::ListStore> freesound_list;
|
||||||
|
|
||||||
Gtk::Button freesound_more_btn;
|
Gtk::Button freesound_more_btn;
|
||||||
Gtk::Button freesound_stop_btn;
|
Gtk::Button freesound_similar_btn;
|
||||||
|
|
||||||
|
void handle_freesound_results(std::string theString);
|
||||||
public:
|
public:
|
||||||
SoundFileBrowser (std::string title, ARDOUR::Session* _s, bool persistent);
|
SoundFileBrowser (std::string title, ARDOUR::Session* _s, bool persistent);
|
||||||
virtual ~SoundFileBrowser ();
|
virtual ~SoundFileBrowser ();
|
||||||
|
|
@ -177,11 +180,10 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
|
|
||||||
Gtk::Button freesound_search_btn;
|
Gtk::Button freesound_search_btn;
|
||||||
Gtk::TreeView freesound_list_view;
|
Gtk::TreeView freesound_list_view;
|
||||||
Gtk::ProgressBar freesound_progress_bar;
|
Gtk::Notebook notebook;
|
||||||
|
|
||||||
bool freesound_download_cancel;
|
|
||||||
|
|
||||||
void freesound_search();
|
void freesound_search();
|
||||||
|
void refresh_display(std::string ID, std::string file);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool resetting_ourselves;
|
bool resetting_ourselves;
|
||||||
|
|
@ -203,7 +205,6 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
|
|
||||||
static std::string persistent_folder;
|
static std::string persistent_folder;
|
||||||
|
|
||||||
Gtk::Notebook notebook;
|
|
||||||
|
|
||||||
GainMeter* gm;
|
GainMeter* gm;
|
||||||
Gtk::VBox meter_packer;
|
Gtk::VBox meter_packer;
|
||||||
|
|
@ -224,10 +225,11 @@ class SoundFileBrowser : public ArdourWindow
|
||||||
void freesound_list_view_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*);
|
void freesound_list_view_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*);
|
||||||
void freesound_search_clicked ();
|
void freesound_search_clicked ();
|
||||||
void freesound_more_clicked ();
|
void freesound_more_clicked ();
|
||||||
void freesound_stop_clicked ();
|
void freesound_similar_clicked ();
|
||||||
int freesound_page;
|
int freesound_page;
|
||||||
|
|
||||||
void chooser_file_activated ();
|
void chooser_file_activated ();
|
||||||
|
std::string freesound_get_audio_file(Gtk::TreeIter iter);
|
||||||
|
|
||||||
bool on_audio_filter (const Gtk::FileFilter::Info& filter_info);
|
bool on_audio_filter (const Gtk::FileFilter::Info& filter_info);
|
||||||
bool on_midi_filter (const Gtk::FileFilter::Info& filter_info);
|
bool on_midi_filter (const Gtk::FileFilter::Info& filter_info);
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,7 @@ CONFIG_VARIABLE (bool, sound_midi_notes, "sound-midi-notes", false)
|
||||||
CONFIG_VARIABLE (bool, use_plugin_own_gui, "use-plugin-own-gui", true)
|
CONFIG_VARIABLE (bool, use_plugin_own_gui, "use-plugin-own-gui", true)
|
||||||
CONFIG_VARIABLE (uint32_t, max_recent_sessions, "max-recent-sessions", 10)
|
CONFIG_VARIABLE (uint32_t, max_recent_sessions, "max-recent-sessions", 10)
|
||||||
CONFIG_VARIABLE (double, automation_thinning_factor, "automation-thinning-factor", 20.0)
|
CONFIG_VARIABLE (double, automation_thinning_factor, "automation-thinning-factor", 20.0)
|
||||||
|
CONFIG_VARIABLE (std::string, freesound_download_dir, "freesound-download-dir", Glib::get_home_dir() + "/Freesound/snd")
|
||||||
|
|
||||||
/* denormal management */
|
/* denormal management */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue