22#include <libOSC/libosc.h>
23#include <libOSC/OSC-client.h>
29 int real_main(
int argc,
char *argv[], pthread_t *gtk_thread,
ulong id);
31 bool lives_osc_cb_quit(
void *context,
int arglen,
const void *vargs, OSCTimeTag when,
void *ra);
36static volatile bool spinning;
38static char *private_response;
39static pthread_mutex_t spin_mutex = PTHREAD_MUTEX_INITIALIZER;
40static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
41static pthread_cond_t cond_done = PTHREAD_COND_INITIALIZER;
43static bool private_cb(lives::_privateInfo *info,
void *data) {
44 if (info->id == msg_id) {
45 private_response = strdup(info->response);
47 pthread_cond_signal(&cond_done);
64static list<livesAppCtx> appMgr;
66static livesApp *find_instance_for_id(
ulong id) {
67 list<livesAppCtx>::iterator it;
68 for (it = appMgr.begin(); it != appMgr.end(); it++) {
69 if ((*it).id ==
id)
return (*it).app;
87 livesString str(L2U8(this->c_str()));
93 livesString str(F2U8(this->c_str()));
101 livesString str(U82F(this->c_str()));
107 livesString str(U82L(this->c_str()));
114 livesString str(U82L(this->c_str()));
120 livesString str(F2U8(this->c_str()));
121 str.assign(U82L(str.c_str()));
131void livesApp::init(
int argc,
char *oargv[]) {
133 char progname[] =
"lives-exe";
134 if (argc < 0) argc = 0;
137 argv = (
char **)malloc(argc *
sizeof(
char *));
138 argv[0] = strdup(progname);
140 for (
int i = 1; i < argc; i++) {
141 argv[i] = strdup(oargv[i - 1]);
145 livesAppCtx *ctx =
new livesAppCtx;
147 pthread_t *gtk_thread =
new pthread_t;
151 appMgr.push_back(*ctx);
153 m_set =
new set(
this);
154 m_player =
new player(
this);
155 m_effectKeyMap =
new effectKeyMap(
this);
158 m_deinterlace =
false;
160 m_thread = gtk_thread;
169livesApp::livesApp() : m_id(0l) {
175livesApp::livesApp(
int argc,
char *argv[]) : m_id(0l) {
181livesApp::~livesApp() {
182 if (!isValid())
return;
187bool livesApp::isValid()
const {
188 return this != NULL && m_id != 0l;
192bool livesApp::isPlaying()
const {
197bool livesApp::isReady()
const {
202const set &livesApp::getSet() {
207const player &livesApp::getPlayer() {
213 return *m_multitrack;
218 closure *cl =
new closure;
220 cl->object = (livesApp *)
this;
221 cl->cb_type = cb_type;
222 cl->func = (callback_f)func;
224 while (pthread_mutex_trylock(&spin_mutex)) {
226 lives_usleep(
::prefs->sleep_time);
228 ((livesApp *)
this)->m_closures.push_back(cl);
229 pthread_mutex_unlock(&spin_mutex);
235void livesApp::setClosures(closureList cl) {
241ulong livesApp::addCallback(
lives_callback_t cb_type, modeChanged_callback_f func,
void *data)
const {
243 return appendClosure(cb_type, (callback_f)func, data);
248 return appendClosure(cb_type, (callback_f)func, data);
251ulong livesApp::addCallback(
lives_callback_t cb_type, objectDestroyed_callback_f func,
void *data)
const {
253 return appendClosure(cb_type, (callback_f)func, data);
258 return appendClosure(cb_type, (callback_f)func, data);
261bool livesApp::removeCallback(
ulong id)
const {
262 while (pthread_mutex_trylock(&spin_mutex)) {
264 lives_usleep(
::prefs->sleep_time);
266 closureListIterator it = ((livesApp *)
this)->m_closures.begin();
267 while (it != ((livesApp *)
this)->m_closures.end()) {
268 if ((*it)->id ==
id) {
270 ((livesApp *)
this)->m_closures.erase(it);
271 pthread_mutex_unlock(&spin_mutex);
276 pthread_mutex_unlock(&spin_mutex);
289 pthread_mutex_lock(&cond_mutex);
291 pthread_mutex_unlock(&cond_mutex);
293 removeCallback(cbid);
295 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
296 pthread_mutex_unlock(&cond_mutex);
310livesString livesApp::chooseFileWithPreview(livesString dirname,
lives_filechooser_t preview_type, livesString title) {
311 livesString emptystr;
317 pthread_mutex_lock(&cond_mutex);
320 preview_type, msg_id)) {
321 pthread_mutex_unlock(&cond_mutex);
323 removeCallback(cbid);
325 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
326 pthread_mutex_unlock(&cond_mutex);
330 m_deinterlace = (bool)atoi(private_response + strlen(private_response) - 2);
339livesString livesApp::chooseSet() {
340 livesString emptystr;
345 pthread_mutex_lock(&cond_mutex);
347 pthread_mutex_unlock(&cond_mutex);
349 removeCallback(cbid);
351 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
352 pthread_mutex_unlock(&cond_mutex);
363livesStringList livesApp::availableSets() {
364 livesStringList list;
367 while (slist != NULL) {
372 lives_list_free(setlist);
377clip livesApp::openFile(livesString fname,
bool with_audio,
double stime,
int frames,
bool deinterlace) {
379 if (fname.empty())
return clip();
385 pthread_mutex_lock(&cond_mutex);
387 pthread_mutex_unlock(&cond_mutex);
389 removeCallback(cbid);
391 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
392 pthread_mutex_unlock(&cond_mutex);
394 cid = strtoul(private_response, NULL, 10);
398 return clip(cid,
this);
402bool livesApp::reloadSet(livesString setname) {
408 pthread_mutex_lock(&cond_mutex);
410 pthread_mutex_unlock(&cond_mutex);
412 removeCallback(cbid);
415 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
416 pthread_mutex_unlock(&cond_mutex);
418 bool ret = (bool)atoi(private_response);
426bool livesApp::deinterlaceOption() {
427 return m_deinterlace;
444 pthread_mutex_lock(&cond_mutex);
446 pthread_mutex_unlock(&cond_mutex);
448 removeCallback(cbid);
451 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
452 pthread_mutex_unlock(&cond_mutex);
470bool livesApp::cancel() {
471 if (!isValid())
return false;
478 pthread_mutex_lock(&cond_mutex);
480 pthread_mutex_unlock(&cond_mutex);
482 removeCallback(cbid);
485 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
486 pthread_mutex_unlock(&cond_mutex);
488 ret = (bool)atoi(private_response);
496closureList &livesApp::closures() {
502void livesApp::invalidate() {
507bool livesApp::interactive() {
508 return mainw->interactive;
512bool livesApp::setInteractive(
bool setting) {
517 pthread_mutex_lock(&cond_mutex);
519 pthread_mutex_unlock(&cond_mutex);
521 removeCallback(cbid);
523 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
524 pthread_mutex_unlock(&cond_mutex);
532const effectKeyMap &livesApp::getEffectKeyMap() {
533 return *m_effectKeyMap;
538bool livesApp::setPref(
const char *prefidx,
bool val)
const {
543 pthread_mutex_lock(&cond_mutex);
545 pthread_mutex_unlock(&cond_mutex);
547 removeCallback(cbid);
550 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
551 pthread_mutex_unlock(&cond_mutex);
558bool livesApp::setPref(
const char *prefidx,
int val)
const {
563 pthread_mutex_lock(&cond_mutex);
565 pthread_mutex_unlock(&cond_mutex);
567 removeCallback(cbid);
570 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
571 pthread_mutex_unlock(&cond_mutex);
578bool livesApp::setPref(
const char *prefidx,
int bitfield,
bool val)
const {
583 pthread_mutex_lock(&cond_mutex);
585 pthread_mutex_unlock(&cond_mutex);
587 removeCallback(cbid);
590 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
591 pthread_mutex_unlock(&cond_mutex);
601player::player(livesApp *
lives) {
607bool player::isValid()
const {
612bool player::isPlaying()
const {
613 return isValid() && m_lives->isPlaying();
617bool player::isRecording()
const {
622bool player::play()
const {
623 if (!isValid() || !m_lives->isReady())
return false;
628bool player::stop()
const {
629 if (!isPlaying())
return false;
633 pthread_mutex_lock(&cond_mutex);
635 pthread_mutex_unlock(&cond_mutex);
637 m_lives->removeCallback(cbid);
640 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
641 pthread_mutex_unlock(&cond_mutex);
643 bool ret = atoi(private_response);
651void player::setSepWin(
bool setting)
const {
652 if (!isValid())
return;
656 pthread_mutex_lock(&cond_mutex);
658 pthread_mutex_unlock(&cond_mutex);
660 m_lives->removeCallback(cbid);
663 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
664 pthread_mutex_unlock(&cond_mutex);
672void player::setFullScreen(
bool setting)
const {
673 if (!isValid())
return;
677 pthread_mutex_lock(&cond_mutex);
679 pthread_mutex_unlock(&cond_mutex);
681 m_lives->removeCallback(cbid);
684 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
685 pthread_mutex_unlock(&cond_mutex);
693bool player::sepWin()
const {
694 if (!isValid())
return false;
699bool player::fullScreen()
const {
700 if (!isValid())
return false;
705bool player::setForegroundClip(clip c)
const {
706 if (!isPlaying())
return false;
711bool player::setBackgroundClip(clip c)
const {
712 if (!isPlaying())
return false;
713 return c.setIsBackground();
717clip player::foregroundClip()
const {
718 if (!isPlaying())
return clip();
719 if (m_lives->m_multitrack->isActive())
return clip();
724clip player::backgroundClip()
const {
725 if (!isPlaying())
return clip();
726 if (m_lives->m_multitrack->isActive())
return clip();
731void player::setFS(
bool setting)
const {
732 if (!isValid())
return;
736 pthread_mutex_lock(&cond_mutex);
738 pthread_mutex_unlock(&cond_mutex);
740 m_lives->removeCallback(cbid);
743 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
744 pthread_mutex_unlock(&cond_mutex);
752double player::videoPlaybackTime(
bool background)
const {
753 if (!isValid())
return 0.;
757 if (!m_lives->m_multitrack->isActive()) {
760 if (!background)
return (
cfile->frameno - 1.) /
cfile->fps;
764 }
else return cfile->pointer_time;
771double player::audioPlaybackTime()
const {
772 if (!isValid())
return 0.;
776 if (!m_lives->m_multitrack->isActive()) {
779 else return cfile->pointer_time;
786double player::setAudioPlaybackTime(
double time)
const {
787 if (!isValid())
return 0.;
788 if (!m_lives->isPlaying())
return 0.;
792 if (time < 0. || time >
cfile->laudio_time)
return 0.;
797 pthread_mutex_lock(&cond_mutex);
799 pthread_mutex_unlock(&cond_mutex);
801 m_lives->removeCallback(cbid);
803 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
804 pthread_mutex_unlock(&cond_mutex);
809 return audioPlaybackTime();
813double player::setPlaybackStartTime(
double time)
const {
814 if (!isValid())
return 0.;
815 if (!m_lives->isReady())
return 0.;
820 pthread_mutex_lock(&cond_mutex);
822 pthread_mutex_unlock(&cond_mutex);
824 m_lives->removeCallback(cbid);
826 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
827 pthread_mutex_unlock(&cond_mutex);
832 return videoPlaybackTime();
836int player::setVideoPlaybackFrame(
int frame,
bool bg)
const {
837 if (!isValid())
return 0;
842 pthread_mutex_lock(&cond_mutex);
844 pthread_mutex_unlock(&cond_mutex);
846 m_lives->removeCallback(cbid);
848 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
849 pthread_mutex_unlock(&cond_mutex);
854 return videoPlaybackTime();
858double player::elapsedTime()
const {
859 if (!isPlaying())
return 0.;
864double player::currentFPS()
const {
865 if (!isValid())
return 0.;
868 return cfile->pb_fps;
872double player::setCurrentFPS(
double fps)
const {
873 if (!isPlaying())
return 0.;
878 pthread_mutex_lock(&cond_mutex);
880 pthread_mutex_unlock(&cond_mutex);
882 m_lives->removeCallback(cbid);
884 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
885 pthread_mutex_unlock(&cond_mutex);
894int player::currentAudioRate()
const {
895 if (!isValid())
return 0.;
903 if (!isValid())
return loopMode();
907 pthread_mutex_lock(&cond_mutex);
909 pthread_mutex_unlock(&cond_mutex);
911 m_lives->removeCallback(cbid);
913 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
914 pthread_mutex_unlock(&cond_mutex);
934bool player::setPingPong(
bool setting)
const {
935 if (!isValid())
return pingPong();
939 pthread_mutex_lock(&cond_mutex);
941 pthread_mutex_unlock(&cond_mutex);
943 m_lives->removeCallback(cbid);
945 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
946 pthread_mutex_unlock(&cond_mutex);
955bool player::pingPong()
const {
956 if (!isValid())
return false;
961bool player::resyncFPS()
const {
962 if (!isPlaying())
return false;
966 pthread_mutex_lock(&cond_mutex);
968 pthread_mutex_unlock(&cond_mutex);
970 m_lives->removeCallback(cbid);
972 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
973 pthread_mutex_unlock(&cond_mutex);
984set::set(livesApp *
lives) {
989bool set::isValid()
const {
994livesString set::name()
const {
995 if (!isValid())
return livesString();
1000bool set::setName(livesString name)
const {
1001 if (!isValid())
return false;
1003 if (numClips() == 0)
return false;
1005 if (!name.empty()) {
1018 pthread_mutex_lock(&cond_mutex);
1020 pthread_mutex_unlock(&cond_mutex);
1022 m_lives->removeCallback(cbid);
1025 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1026 pthread_mutex_unlock(&cond_mutex);
1028 bool ret = (bool)atoi(private_response);
1036unsigned int set::numClips()
const {
1037 if (!isValid())
return 0;
1038 (
const_cast<set *
>(
this))->update_clip_list();
1039 return m_clips.size();
1043clip set::nthClip(
unsigned int n)
const {
1044 if (!isValid())
return clip();
1045 (
const_cast<set *
>(
this))->update_clip_list();
1046 if (n >= m_clips.size())
return clip();
1047 return clip(m_clips[n], m_lives);
1051int set::indexOf(clip c)
const {
1052 if (!isValid())
return -1;
1053 if (!c.isValid())
return -1;
1054 if (m_clips.empty())
return -1;
1055 (
const_cast<set *
>(
this))->update_clip_list();
1057 for (i = 0; i < (int)m_clips.size(); i++) {
1058 if (m_clips[i] == c.m_uid)
return i;
1064bool set::save(livesString name,
bool force_append)
const {
1065 if (!isValid())
return FALSE;
1075 pthread_mutex_lock(&cond_mutex);
1077 pthread_mutex_unlock(&cond_mutex);
1079 m_lives->removeCallback(cbid);
1081 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1082 pthread_mutex_unlock(&cond_mutex);
1084 ret = (bool)(atoi(private_response));
1092bool set::save()
const {
1093 return save(name());
1097void set::update_clip_list() {
1098 clipListIterator it = m_clips.begin();
1099 while (it != m_clips.end()) {
1100 it = m_clips.erase(it);
1105 for (
int i = 0; ids[i] != 0l; i++) {
1106 m_clips.push_back(ids[i]);
1115clip::clip() : m_uid(0l), m_lives(NULL) {};
1122bool clip::isValid()
const {
1159double clip::playbackFPS() {
1161 if (!m_lives->m_multitrack->isActive()) {
1164 }
else return m_lives->m_multitrack->FPS();
1170int clip::audioRate() {
1179int clip::playbackAudioRate() {
1182 if (!m_lives->m_multitrack->isActive()) {
1184 if (cnum > -1 &&
mainw->
files[cnum] != NULL) {
1194double clip::audioLength() {
1203int clip::audioChannels() {
1212int clip::audioSampleSize() {
1221bool clip::audioSigned() {
1233 if (cnum > -1 &&
mainw->
files[cnum] != NULL) {
1241livesString clip::name() {
1247 return livesString();
1251int clip::selectionStart() {
1260int clip::selectionEnd() {
1269bool clip::selectAll() {
1276 pthread_mutex_lock(&cond_mutex);
1278 pthread_mutex_unlock(&cond_mutex);
1280 m_lives->removeCallback(cbid);
1283 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1284 pthread_mutex_unlock(&cond_mutex);
1286 bool ret = (bool)atoi(private_response);
1294bool clip::setSelectionStart(
unsigned int frame) {
1295 if (!isValid())
return false;
1301 pthread_mutex_lock(&cond_mutex);
1303 pthread_mutex_unlock(&cond_mutex);
1305 m_lives->removeCallback(cbid);
1308 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1309 pthread_mutex_unlock(&cond_mutex);
1311 bool ret = (bool)atoi(private_response);
1319bool clip::setSelectionEnd(
unsigned int frame) {
1320 if (!isValid())
return false;
1326 pthread_mutex_lock(&cond_mutex);
1328 pthread_mutex_unlock(&cond_mutex);
1330 m_lives->removeCallback(cbid);
1333 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1334 pthread_mutex_unlock(&cond_mutex);
1336 bool ret = (bool)atoi(private_response);
1344bool clip::switchTo() {
1345 if (!isValid())
return false;
1346 if (m_lives->m_multitrack->isActive())
return false;
1352 pthread_mutex_lock(&cond_mutex);
1354 pthread_mutex_unlock(&cond_mutex);
1356 m_lives->removeCallback(cbid);
1359 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1360 pthread_mutex_unlock(&cond_mutex);
1362 bool ret = (bool)atoi(private_response);
1370bool clip::setIsBackground() {
1371 if (!isValid())
return false;
1372 if (m_lives->m_multitrack->isActive())
return false;
1378 pthread_mutex_lock(&cond_mutex);
1380 pthread_mutex_unlock(&cond_mutex);
1382 m_lives->removeCallback(cbid);
1385 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1386 pthread_mutex_unlock(&cond_mutex);
1388 bool ret = (bool)atoi(private_response);
1398effectKeyMap::effectKeyMap(livesApp *
lives) {
1403bool effectKeyMap::isValid()
const {
1408effectKey effectKeyMap::at(
int i)
const {
1413size_t effectKeyMap::size()
const {
1414 if (!isValid())
return 0;
1419bool effectKeyMap::clear()
const {
1420 if (!isValid())
return false;
1425 pthread_mutex_lock(&cond_mutex);
1427 pthread_mutex_unlock(&cond_mutex);
1429 m_lives->removeCallback(cbid);
1432 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1433 pthread_mutex_unlock(&cond_mutex);
1435 bool ret = (bool)atoi(private_response);
1446effectKey::effectKey() {
1451effectKey::effectKey(livesApp *
lives,
int key) {
1457bool effectKey::isValid()
const {
1463int effectKey::key() {
1468int effectKey::numModes() {
1469 if (!isValid())
return 0;
1474int effectKey::numMappedModes() {
1475 if (!isValid())
return 0;
1480int effectKey::currentMode() {
1481 if (!isValid())
return -1;
1486bool effectKey::enabled() {
1487 if (!isValid())
return false;
1492int effectKey::setCurrentMode(
int new_mode) {
1493 if (!isValid())
return -1;
1494 if (new_mode < 0 || new_mode >= numMappedModes())
return currentMode();
1496 if (new_mode == currentMode())
return currentMode();
1502 pthread_mutex_lock(&cond_mutex);
1504 pthread_mutex_unlock(&cond_mutex);
1506 m_lives->removeCallback(cbid);
1507 return currentMode();
1509 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1510 pthread_mutex_unlock(&cond_mutex);
1514 return currentMode();
1518bool effectKey::setEnabled(
bool setting) {
1519 if (!isValid())
return false;
1525 pthread_mutex_lock(&cond_mutex);
1528 m_lives->removeCallback(cbid);
1531 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1532 pthread_mutex_unlock(&cond_mutex);
1543int effectKey::appendMapping(effect fx) {
1544 if (!isValid())
return -1;
1546 if (!fx.isValid())
return -1;
1548 if (fx.m_lives != m_lives)
return -1;
1550 if (!m_lives->isReady() && !m_lives->isPlaying())
return -1;
1552 int mode = numMappedModes();
1553 if (mode == numModes())
return -1;
1559 pthread_mutex_lock(&cond_mutex);
1560 if (!
idle_map_fx(m_key, mode, fx.m_idx, msg_id)) {
1561 pthread_mutex_unlock(&cond_mutex);
1563 m_lives->removeCallback(cbid);
1566 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1567 pthread_mutex_unlock(&cond_mutex);
1569 bool ret = (bool)atoi(private_response);
1571 if (ret)
return mode;
1577bool effectKey::removeMapping(
int mode) {
1578 if (!isValid())
return false;
1580 if (!m_lives->isReady() && !m_lives->isPlaying())
return false;
1582 if (mode >= numMappedModes())
return false;
1588 pthread_mutex_lock(&cond_mutex);
1590 pthread_mutex_unlock(&cond_mutex);
1592 m_lives->removeCallback(cbid);
1595 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1596 pthread_mutex_unlock(&cond_mutex);
1598 bool ret = (bool)atoi(private_response);
1606effect effectKey::at(
int mode) {
1608 if (!isValid())
return e;
1610 if (idx == -1)
return e;
1611 e = effect(m_lives, idx);
1618effect::effect(
const livesApp &
lives, livesString hashname,
bool match_full) {
1620 m_lives = (livesApp *)&
lives;
1626effect::effect(
const livesApp &
lives, livesString package, livesString fxname, livesString author,
int version) {
1628 m_lives = (livesApp *)&
lives;
1637bool effect::isValid()
const {
1638 return (m_idx != -1 && m_lives != NULL && m_lives->isValid() && m_lives->status() !=
LIVES_STATUS_NOTREADY);
1642effect::effect() : m_lives(NULL), m_idx(-1) {}
1644effect::effect(livesApp *
lives,
int idx) : m_lives(
lives), m_idx(idx) {}
1651 if (m == NULL) m_lives = NULL;
1652 else m_lives = m->m_lives;
1656block::block(
multitrack m,
int track,
double time) {
1657 m_lives = m.m_lives;
1658 if (!m.isActive()) m_uid = 0l;
1661 if (tr == NULL) m_uid = 0l;
1662 else m_uid = tr->uid;
1667bool block::isValid()
const {
1668 if (m_lives == NULL || !m_lives->isValid() || !m_lives->m_multitrack->isActive() || m_uid == 0l ||
1674void block::invalidate() {
1679double block::startTime() {
1681 if (tr == NULL)
return -1.;
1686double block::length() {
1688 if (tr == NULL)
return -1.;
1694clip block::clipSource() {
1696 if (tr == NULL)
return clip();
1698 if (cnum == -1)
return clip();
1705 if (tr == NULL)
return 0;
1710bool block::remove() {
1711 if (!isValid())
return false;
1712 if (!m_lives->isReady())
return false;
1715 if (tr == NULL)
return false;
1720 pthread_mutex_lock(&cond_mutex);
1722 pthread_mutex_unlock(&cond_mutex);
1724 m_lives->removeCallback(cbid);
1727 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1728 pthread_mutex_unlock(&cond_mutex);
1730 bool ret = (bool)atoi(private_response);
1732 if (ret) invalidate();
1739bool block::moveTo(
int track,
double time) {
1740 if (!isValid())
return false;
1741 if (!m_lives->isReady())
return false;
1744 if (tr == NULL)
return false;
1749 pthread_mutex_lock(&cond_mutex);
1751 pthread_mutex_unlock(&cond_mutex);
1753 m_lives->removeCallback(cbid);
1756 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1757 pthread_mutex_unlock(&cond_mutex);
1759 bool ret = (bool)atoi(private_response);
1761 if (ret) invalidate();
1776bool multitrack::isValid()
const {
1781bool multitrack::isActive()
const {
1786double multitrack::currentTime()
const {
1787 if (!isActive())
return 0.;
1788 return m_lives->m_player->videoPlaybackTime();
1792double multitrack::setCurrentTime(
double time)
const {
1793 if (!isActive() || !m_lives->isReady())
return currentTime();
1794 return m_lives->m_player->setPlaybackStartTime(time);
1798block multitrack::insertBlock(clip c,
bool ign_sel,
bool without_audio)
const {
1799 if (!isActive())
return block();
1800 if (!c.isValid())
return block();
1801 if (!m_lives->isReady())
return block();
1808 pthread_mutex_lock(&cond_mutex);
1810 pthread_mutex_unlock(&cond_mutex);
1812 m_lives->removeCallback(cbid);
1815 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1816 pthread_mutex_unlock(&cond_mutex);
1818 ulong uid = strtoul(private_response, NULL, 10);
1820 return block(
const_cast<multitrack *
>(
this), uid);
1826livesString multitrack::wipeLayout(
bool force)
const {
1827 livesString emptystr;
1828 if (!isActive())
return emptystr;
1829 if (!m_lives->isReady())
return emptystr;
1835 pthread_mutex_lock(&cond_mutex);
1837 pthread_mutex_unlock(&cond_mutex);
1839 m_lives->removeCallback(cbid);
1842 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1843 pthread_mutex_unlock(&cond_mutex);
1853livesString multitrack::chooseLayout()
const {
1854 livesString emptystr;
1855 if (!isActive())
return emptystr;
1856 if (!m_lives->isReady())
return emptystr;
1862 pthread_mutex_lock(&cond_mutex);
1864 pthread_mutex_unlock(&cond_mutex);
1866 m_lives->removeCallback(cbid);
1869 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1870 pthread_mutex_unlock(&cond_mutex);
1880livesStringList multitrack::availableLayouts()
const {
1881 livesStringList list;
1882 if (!isValid())
return list;
1884 while (layoutlist != NULL) {
1888 layoutlist = layoutlist->next;
1894bool multitrack::reloadLayout(livesString layoutname)
const {
1895 if (!isActive())
return false;
1896 if (!m_lives->isReady())
return false;
1902 pthread_mutex_lock(&cond_mutex);
1904 pthread_mutex_unlock(&cond_mutex);
1906 m_lives->removeCallback(cbid);
1909 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1910 pthread_mutex_unlock(&cond_mutex);
1912 bool ret = (bool)atoi(private_response);
1920livesString multitrack::saveLayout(livesString name)
const {
1921 livesString emptystr;
1922 if (!isActive())
return emptystr;
1923 if (!m_lives->isReady())
return emptystr;
1929 pthread_mutex_lock(&cond_mutex);
1931 pthread_mutex_unlock(&cond_mutex);
1933 m_lives->removeCallback(cbid);
1936 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1937 pthread_mutex_unlock(&cond_mutex);
1939 char *lname = strdup(private_response);
1947livesString multitrack::saveLayout()
const {
1948 livesString emptystr;
1949 if (!isActive())
return emptystr;
1950 if (!m_lives->isReady())
return emptystr;
1956 pthread_mutex_lock(&cond_mutex);
1958 pthread_mutex_unlock(&cond_mutex);
1960 m_lives->removeCallback(cbid);
1963 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1964 pthread_mutex_unlock(&cond_mutex);
1966 char *lname = strdup(private_response);
1976 if (!isActive())
return c;
1977 if (!m_lives->isReady())
return c;
1983 pthread_mutex_lock(&cond_mutex);
1985 pthread_mutex_unlock(&cond_mutex);
1987 m_lives->removeCallback(cbid);
1990 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
1991 pthread_mutex_unlock(&cond_mutex);
1993 ulong uid = strtoul(private_response, NULL, 10);
1994 c = clip(uid, m_lives);
2001effect multitrack::autoTransition()
const {
2004 if (
::prefs->atrans_fx == -1)
return e;
2005 e = effect(m_lives,
::prefs->atrans_fx);
2010bool multitrack::setAutoTransition(effect autotrans)
const {
2011 if (!m_lives->isValid())
return false;
2012 if (!autotrans.isValid())
return disableAutoTransition();
2023bool multitrack::disableAutoTransition()
const {
2024 if (!m_lives->isValid())
return false;
2031int multitrack::currentTrack()
const {
2032 if (!isActive())
return 0;
2037bool multitrack::setCurrentTrack(
int track)
const {
2039 if (!isActive())
return false;
2044 pthread_mutex_lock(&cond_mutex);
2046 pthread_mutex_unlock(&cond_mutex);
2048 m_lives->removeCallback(cbid);
2050 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
2051 pthread_mutex_unlock(&cond_mutex);
2053 bool ret = (bool)(atoi(private_response));
2062livesString multitrack::trackLabel(
int track)
const {
2063 livesString emptystr;
2064 if (!isActive())
return emptystr;
2075double multitrack::FPS()
const {
2076 if (!isActive())
return 0.;
2081bool multitrack::setTrackLabel(
int track, livesString label)
const {
2083 if (!isActive())
return false;
2088 pthread_mutex_lock(&cond_mutex);
2090 pthread_mutex_unlock(&cond_mutex);
2092 m_lives->removeCallback(cbid);
2094 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
2095 pthread_mutex_unlock(&cond_mutex);
2097 bool ret = (bool)(atoi(private_response));
2121 if (!isActive())
return gravity();
2126 pthread_mutex_lock(&cond_mutex);
2128 pthread_mutex_unlock(&cond_mutex);
2130 m_lives->removeCallback(cbid);
2132 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
2133 pthread_mutex_unlock(&cond_mutex);
2153 if (!isActive())
return insertMode();
2158 pthread_mutex_lock(&cond_mutex);
2160 pthread_mutex_unlock(&cond_mutex);
2162 m_lives->removeCallback(cbid);
2164 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
2165 pthread_mutex_unlock(&cond_mutex);
2170 return insertMode();
2174int multitrack::numAudioTracks()
const {
2175 if (!isActive())
return 0;
2180int multitrack::numVideoTracks()
const {
2181 if (!isActive())
return 0;
2186int multitrack::addVideoTrack(
bool in_front)
const {
2187 if (!isActive())
return -1;
2188 if (m_lives->isReady())
return -1.;
2193 pthread_mutex_lock(&cond_mutex);
2195 pthread_mutex_unlock(&cond_mutex);
2197 m_lives->removeCallback(cbid);
2199 while (spinning) pthread_cond_wait(&cond_done, &cond_mutex);
2200 pthread_mutex_unlock(&cond_mutex);
2202 int tnum = atoi(private_response);
2238 if (!
lives.isReady())
return false;
2255#ifdef HAVE_PULSE_AUDIO
2328 lives::livesApp *lapp;
2331 else lapp = lives::find_instance_for_id(
id);
2333 if (lapp == NULL)
return;
2335 pthread_mutex_lock(&spin_mutex);
2337 lives::closureList cl = lapp->closures();
2339 lives::closureListIterator it = cl.begin();
2340 while (it != cl.end()) {
2341 if ((*it)->cb_type == cb_type) {
2344 lives::modeChangedInfo info;
2346 lives::modeChanged_callback_f fn = (lives::modeChanged_callback_f)((*it)->func);
2347 ret = (fn)((*it)->object, &info, (*it)->data);
2352 lives::appQuitInfo info;
2353 info.signum = atoi(msgstring);
2354 lives::appQuit_callback_f fn = (lives::appQuit_callback_f)((*it)->func);
2356 ret = (fn)((*it)->object, &info, (*it)->data);
2361 lives::objectDestroyed_callback_f fn = (lives::objectDestroyed_callback_f)((*it)->func);
2362 ret = (fn)((*it)->object, (*it)->data);
2367 lives::_privateInfo info;
2369 info.id = strtoul(msgstring, &endptr, 10);
2370 info.response = endptr + 1;
2371 lives::private_callback_f fn = (lives::private_callback_f)((*it)->func);
2372 ret = (fn)(&info, (*it)->data);
2382 lapp->setClosures(cl);
2389 pthread_mutex_unlock(&spin_mutex);
boolean normalise_audio(int fnum, double start, double end, float thresh)
#define is_realtime_aplayer(ptype)
int weed_get_idx_for_hashname(const char *hashname, boolean fullname)
fullname includes author and version
int rte_keymode_get_filter_idx(int key, int mode)
returns filter_class index of key/mode (or -1 if no filter bound)
weed_plant_t * get_weed_filter(int idx)
int get_transition_param(weed_plant_t *filter, boolean skip_internal)
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
char * get_menu_name(lives_clip_t *sfile, boolean add_setname)
boolean idle_remove_block(ulong uid, ulong id)
boolean idle_mt_set_track(int tnum, ulong id)
boolean idle_reload_layout(const char *lname, ulong id)
boolean idle_set_interactive(boolean setting, ulong id)
int get_first_fx_matched(const char *package, const char *fxname, const char *author, int version)
boolean idle_set_current_audio_time(double time, ulong id)
ulong * get_unique_ids(void)
utility functions for liblives /////
boolean idle_fx_setmode(int key, int mode, ulong id)
boolean start_player(void)
boolean idle_set_loop_mode(int mode, ulong id)
boolean idle_select_all(int cnum, ulong id)
boolean idle_set_gravity(int grav, ulong id)
boolean idle_insert_vtrack(boolean in_front, ulong id)
boolean get_rte_key_is_enabled(int key)
boolean idle_select_start(int cnum, int frame, ulong id)
boolean idle_show_info(const char *text, boolean blocking, ulong id)
idlefunc hooks
boolean idle_set_current_time(double time, ulong id)
boolean idle_set_sepwin(boolean setting, ulong id)
boolean idle_insert_block(int clipno, boolean ign_sel, boolean with_audio, ulong id)
boolean idle_wipe_layout(boolean force, ulong id)
boolean idle_set_current_frame(int frame, boolean bg, ulong id)
boolean idle_quit(pthread_t *gtk_thread)
int get_current_mode_for_key(int key)
boolean idle_render_layout(boolean with_aud, boolean normalise_aud, ulong id)
boolean idle_switch_clip(int type, int cnum, ulong id)
boolean idle_set_pref_int(const char *prefidx, int val, ulong id)
boolean idle_move_block(ulong uid, int track, double time, ulong id)
boolean idle_set_ping_pong(boolean setting, ulong id)
boolean idle_save_layout(const char *lname, ulong id)
boolean idle_set_fullscreen_sepwin(boolean setting, ulong id)
boolean idle_save_set(const char *name, boolean force_append, ulong id)
boolean idle_fx_enable(int key, boolean setting, ulong id)
boolean idle_unmap_effects(ulong id)
boolean idle_set_insert_mode(int mode, ulong id)
boolean idle_set_current_fps(double fps, ulong id)
boolean idle_choose_layout(ulong id)
boolean idle_choose_set(ulong id)
boolean idle_reload_set(const char *setname, ulong id)
boolean idle_set_pref_bitmapped(const char *prefidx, int bitfield, boolean val, ulong id)
boolean idle_map_fx(int key, int mode, int idx, ulong id)
boolean idle_cancel_proc(ulong id)
boolean idle_set_track_label(int tnum, const char *label, ulong id)
boolean idle_set_set_name(ulong id)
boolean idle_resync_fps(ulong id)
boolean idle_select_end(int cnum, int frame, ulong id)
boolean idle_set_pref_bool(const char *prefidx, boolean val, ulong id)
boolean idle_open_file(const char *fname, double stime, int frames, ulong id)
boolean idle_stop_playback(ulong id)
int cnum_for_uid(ulong uid)
boolean idle_set_if_mode(lives_interface_mode_t mode, ulong id)
int get_num_mapped_modes_for_key(int key)
boolean idle_unmap_fx(int key, int mode, ulong id)
boolean idle_set_fullscreen(boolean setting, ulong id)
boolean idle_choose_file_with_preview(const char *dirname, const char *title, int preview_type, ulong id)
track_rect * find_block_by_uid(lives_mt *mt, ulong uid)
bool lives_osc_cb_quit(void *context, int arglen, const void *vargs, OSCTimeTag when, void *ra)
void binding_cb(lives_callback_t cb_type, const char *msgstring, ulong id)
int real_main(int argc, char *argv[], pthread_t *gtk_thread, ulong id)
Header file for liblives.
lives_filechooser_t
Filechooser hinting types.
@ LIVES_FILE_CHOOSER_AUDIO_ONLY
file chooser options for single audio file
@ LIVES_FILE_CHOOSER_VIDEO_AUDIO
file chooser options for single video or audio file
lives_endian_t
Endian values.
lives_interface_mode_t
LiVES operation mode.
@ LIVES_INTERFACE_MODE_MULTITRACK
multitrack mode
@ LIVES_INTERFACE_MODE_INVALID
livesApp instance is invalid
@ LIVES_INTERFACE_MODE_CLIPEDIT
clip editor mode
lives_insert_mode_t
Multitrack insert modes.
@ LIVES_INSERT_MODE_NORMAL
lives_status_t
LiVES operational status.
@ LIVES_STATUS_INVALID
livesApp instance is invalid
@ LIVES_STATUS_PLAYING
application is playing, only player commands will be responded to
@ LIVES_STATUS_NOTREADY
application is starting up; not ready
@ LIVES_STATUS_PROCESSING
application is processing, commands will be ignored
@ LIVES_STATUS_READY
application is ready for commands
@ LIVES_STATUS_PREVIEW
user is previewing an operation, commands will be ignored
lives_audio_player_t
Audio players.
@ LIVES_AUDIO_PLAYER_SOX
Audio playback is through Sox.
@ LIVES_AUDIO_PLAYER_JACK
Audio playback is thorugh Jack.
@ LIVES_AUDIO_PLAYER_PULSE
Audio playback is through PulseAudio.
@ LIVES_AUDIO_PLAYER_UNKNOWN
Unknown / invalid.
lives_callback_t
Callback types.
@ LIVES_CALLBACK_APP_QUIT
sent when app quits
@ LIVES_CALLBACK_MODE_CHANGED
sent when interface mode changes
@ LIVES_CALLBACK_OBJECT_DESTROYED
sent when livesApp object is deleted
@ LIVES_CALLBACK_PRIVATE
for internal use
lives_gravity_t
Multitrack gravity.
@ LIVES_GRAVITY_LEFT
inserted blocks gravitate to the left
@ LIVES_GRAVITY_RIGHT
inserted blocks gravitate to the right
@ LIVES_GRAVITY_NORMAL
no gravity
lives_loop_mode_t
Player looping modes (bitmap)
@ LIVES_LOOP_MODE_FIT_AUDIO
video keeps looping until audio playback finishes
@ LIVES_LOOP_MODE_CONTINUOUS
both video and audio loop continuously
@ LIVES_LOOP_MODE_NONE
no looping
lives_char_encoding_t
Character encoding types.
@ LIVES_CHAR_ENCODING_LOCAL8BIT
8 bit locale file encoding
@ LIVES_CHAR_ENCODING_FILESYSTEM
file system encoding (UTF-8 on windows, local8bit on others)
@ LIVES_CHAR_ENCODING_UTF8
UTF-8 char encoding.
lives_audio_source_t
Audio sources.
@ LIVES_AUDIO_SOURCE_EXTERNAL
Audio source is external to LiVES.
@ LIVES_AUDIO_SOURCE_INTERNAL
Audio source is internal to LiVES.
@ LIVES_AUDIO_SOURCE_UNKNOWN
Unknown / invalid.
lives_dialog_response_t
Dialog response values.
@ LIVES_DIALOG_RESPONSE_INVALID
INVALID response.
@ LIVES_DIALOG_RESPONSE_NONE
Response not obtained.
LIVES_GLOBAL_INLINE uint64_t lives_random(void)
char * repl_workdir(const char *entry, boolean fwd)
LiVESList * get_set_list(const char *dir, boolean utf8)
#define FPS_MAX
maximum fps we will allow (double)
boolean is_legal_set_name(const char *set_name, boolean allow_dupes, boolean leeway)
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
boolean mt_track_is_audio(lives_mt *mt, int ntrack)
return TRUE if ntrack is a valid backing audio track
void mt_set_autotrans(int idx)
track_rect * get_block_from_track_and_time(lives_mt *mt, int track, double time)
get timeline end time of block
boolean mt_track_is_video(lives_mt *mt, int ntrack)
return TRUE if ntrack is a valid video track
lives_mt * multitrack(weed_plant_t *event_list, int orig_file, double fps)
create and return lives_mt struct
int get_track_for_block(track_rect *block)
return track number for a given block
char * get_track_name(lives_mt *mt, int track_num, boolean is_audio)
int get_clip_for_block(track_rect *block)
bool setAudioSource(const livesApp &lives, lives_audio_source_t asrc)
bool isRealtimeAudioPlayer(lives_audio_player_t player_type)
bool audioFollowsVideoChanges(const livesApp &lives)
bool setAudioFollowsVideoChanges(const livesApp &lives, bool setting)
lives_audio_source_t audioSource(const livesApp &lives)
bool setSepWinSticky(const livesApp &lives, bool setting)
bool audioFollowsFPSChanges(const livesApp &lives)
bool setAudioFollowsFPSChanges(const livesApp &lives, bool setting)
livesString currentAudioDir(const livesApp &lives)
lives_audio_player_t audioPlayer(const livesApp &lives)
bool mtExitRender(const livesApp &lives)
int rteKeysVirtual(const livesApp &lives)
livesString currentVideoLoadDir(const livesApp &lives)
double maxFPS(const livesApp &lives)
int audioPlayerRate(const livesApp &lives)
livesString tmpDir(const livesApp &lives)
bool setMtExitRender(const livesApp &lives, bool setting)
bool sepWinSticky(const livesApp &lives)
#define PREF_REC_EXT_AUDIO
#define SEPWIN_TYPE_NON_STICKY
#define AUDIO_OPTS_FOLLOW_CLIPS
#define SEPWIN_TYPE_STICKY
#define PREF_MT_EXIT_RENDER
#define AUDIO_OPTS_FOLLOW_FPS
volatile uint32_t audio_opts
int max_modes_per_key
maximum effect modes per key
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
frames_t frames
number of video frames
int asampsize
audio sample size in bits (8 or 16)
int vsize
frame height (vertical) in pixels
int achans
number of audio channels (0, 1 or 2)
uint32_t signed_endian
bitfield
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
uint64_t unique_id
this and the handle can be used to uniquely id a file
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
int arate
current audio playback rate (varies if the clip rate is changed)
double aframeno
and the audio 'frame' for when we are looping
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
void * pulsed
pulseaudio player
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
volatile boolean loop_cont
void * jackd
jack audio player / transport
int blend_file
background clip details
LiVESList * current_layouts_map
map of all layouts for set
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
volatile boolean ping_pong
boolean is_processing
states
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
char vid_load_dir[PATH_MAX]
weed_event_t * event_list
current event_list, for recording
const char * version(void)