137
void Song::setSig(const AL::TimeSignature& sig)
140
audio->msgAddSig(pos[0].tick(), sig.z, sig.n);
134
144
//---------------------------------------------------------
136
146
// Called from GUI context
137
147
// Besides normal track types, n includes synth menu ids from populateAddTrack()
138
148
//---------------------------------------------------------
140
Track* Song::addNewTrack(int n)
150
Track* Song::addNewTrack(QAction* action)
152
int n = action->data().toInt();
142
153
// Ignore negative numbers since this slot could be called by a menu or list etc. passing -1.
245
256
msgInsertTrack(track, -1, true);
246
257
insertTrack3(track, -1);
259
// Add default track <-> midiport routes.
260
if(track->isMidiTrack())
262
MidiTrack* mt = (MidiTrack*)track;
264
bool defOutFound = false; /// TODO: Remove this if and when multiple output routes supported.
265
for(int i = 0; i < MIDI_PORTS; ++i)
267
MidiPort* mp = &midiPorts[i];
269
if(mp->device()) // Only if device is valid. p4.0.17
271
c = mp->defaultInChannels();
274
audio->msgAddRoute(Route(i, c), Route(track, c));
275
updateFlags |= SC_ROUTE;
281
c = mp->defaultOutChannels();
285
/// TODO: Switch if and when multiple output routes supported.
287
audio->msgAddRoute(Route(track, c), Route(i, c));
288
updateFlags |= SC_ROUTE;
290
for(ch = 0; ch < MIDI_CHANNELS; ++ch)
297
if(type != Track::DRUM) // p4.0.17 Leave drum tracks at channel 10.
298
mt->setOutChannel(ch);
299
updateFlags |= SC_ROUTE;
249
310
// add default route to master
739
803
//startTick = roundDownBar(startTick);
740
804
//endTick = roundUpBar(endTick);
741
805
// Round the start down using the Arranger part snap raster value.
742
startTick = sigmap.raster1(startTick, recRaster());
806
startTick = AL::sigmap.raster1(startTick, arrangerRaster());
743
807
// Round the end up using the Arranger part snap raster value.
744
endTick = sigmap.raster2(endTick, recRaster());
808
endTick = AL::sigmap.raster2(endTick, arrangerRaster());
746
810
part->setTick(startTick);
747
811
part->setLenTick(endTick - startTick);
1014
1078
//---------------------------------------------------------
1015
1079
void Song::setRecord(bool f, bool autoRecEnable)
1082
printf("setRecord recordflag =%d f(record state)=%d autoRecEnable=%d\n", recordFlag, f, autoRecEnable);
1084
if (f && config.useProjectSaveDialog && museProject == museProjectInitPath ) { // check that there is a project stored before commencing
1085
// no project, we need to create one.
1086
if (!muse->saveAs())
1087
return; // could not store project, won't enable record
1017
1089
if (recordFlag != f) {
1018
1090
if (f && autoRecEnable) {
1019
1091
bool alreadyRecEnabled = false;
1211
1292
//---------------------------------------------------------
1294
// setPos slot, only active when not doing playback
1295
//---------------------------------------------------------
1296
void Song::seekTo(int tick)
1298
if (!audio->isPlaying()) {
1303
//---------------------------------------------------------
1213
1305
// song->setPos(Song::CPOS, pos, true, true, true);
1214
1306
//---------------------------------------------------------
1438
sigmap.tickValues(t, &bar, &beat, &tick);
1439
return sigmap.bar2tick(bar, 0, 0);
1530
AL::sigmap.tickValues(t, &bar, &beat, &tick);
1531
return AL::sigmap.bar2tick(bar, 0, 0);
1442
1534
//---------------------------------------------------------
1851
1945
case SEQM_ADD_SIG:
1852
1946
undoOp(UndoOp::AddSig, msg->a, msg->b, msg->c);
1853
sigmap.add(msg->a, msg->b, msg->c);
1947
AL::sigmap.add(msg->a, AL::TimeSignature(msg->b, msg->c));
1854
1948
updateFlags = SC_SIG;
1857
1951
case SEQM_REMOVE_SIG:
1858
1952
undoOp(UndoOp::DeleteSig, msg->a, msg->b, msg->c);
1953
AL::sigmap.del(msg->a);
1860
1954
updateFlags = SC_SIG;
1958
undoOp(UndoOp::AddKey, msg->a, msg->b);
1959
keymap.addKey(msg->a, (key_enum) msg->b);
1960
updateFlags = SC_KEY;
1963
case SEQM_REMOVE_KEY:
1964
undoOp(UndoOp::DeleteKey, msg->a, msg->b);
1965
keymap.delKey(msg->a);
1966
updateFlags = SC_KEY;
1864
1970
printf("unknown seq message %d\n", msg->id);
1986
2094
//if((*imd)->deviceType() == MidiDevice::JACK_MIDI)
1987
2095
if(dynamic_cast< MidiJackDevice* >(*imd))
1989
// Remove the device from the list.
1990
midiDevices.erase(imd);
1991
// Since Jack midi devices are created dynamically, we must delete them.
1992
// The destructor unregisters the device from Jack, which also disconnects all device-to-jack routes.
1993
// This will also delete all midi-track-to-device routes, they point to non-existant midi tracks
1994
// which were all deleted above
2097
//if(clear_all) // Allow not touching devices. p4.0.17 TESTING: Maybe some problems...
2099
// Remove the device from the list.
2100
midiDevices.erase(imd);
2101
// Since Jack midi devices are created dynamically, we must delete them.
2102
// The destructor unregisters the device from Jack, which also disconnects all device-to-jack routes.
2103
// This will also delete all midi-track-to-device routes, they point to non-existant midi tracks
2104
// which were all deleted above
2000
2111
//if((*imd)->deviceType() == MidiDevice::ALSA_MIDI)
2116
2230
// Remove the controllers and the values.
2117
2231
midiPorts[i].controller()->clearDelete(true);
2119
// Can't do this here. Jack isn't running.
2233
// Can't do this here. Jack isn't running. Fixed. Test OK so far.
2122
printf("deleting midi devices\n");
2236
printf("deleting midi devices except synths\n");
2123
2237
for(iMidiDevice imd = midiDevices.begin(); imd != midiDevices.end(); ++imd)
2125
2239
// Since Syntis are midi devices, there's no need to delete them below.
2144
2258
synthis.clear();
2261
printf("deleting midi instruments\n");
2262
for(iMidiInstrument imi = midiInstruments.begin(); imi != midiInstruments.end(); ++imi)
2264
// Since Syntis are midi instruments, there's no need to delete them below.
2265
// Tricky, must cast as SynthI*.
2266
SynthI* s = dynamic_cast <SynthI*> (*imi);
2271
midiInstruments.clear(); // midi devices
2146
2273
// Nothing required for ladspa plugin list, and rack instances of them
2147
2274
// are handled by ~AudioTrack.
2195
2322
// give the user a sensible explanation
2196
int btn = QMessageBox::critical( muse, tr(QString("Jack shutdown!")),
2197
tr(QString("Jack has detected a performance problem which has lead to\n"
2323
int btn = QMessageBox::critical( muse, tr("Jack shutdown!"),
2324
tr("Jack has detected a performance problem which has lead to\n"
2198
2325
"MusE being disconnected.\n"
2199
2326
"This could happen due to a number of reasons:\n"
2200
2327
"- a performance issue with your particular setup.\n"
2341
2468
//enum { HEADER, SEP1, PREV_EVENT, NEXT_EVENT, SEP2, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
2342
2469
enum { HEADER, PREV_EVENT, NEXT_EVENT, SEP2, ADD_EVENT, CLEAR_EVENT, CLEAR_RANGE, CLEAR_ALL_EVENTS };
2343
QPopupMenu* menu = new QPopupMenu;
2470
QMenu* menu = new QMenu;
2346
2473
bool isEvent = false, canSeekPrev = false, canSeekNext = false, canEraseRange = false;
2378
2505
//menu->insertItem(tr("Automation:"), HEADER, HEADER);
2379
2506
//menu->setItemEnabled(HEADER, false);
2380
MenuTitleItem* title = new MenuTitleItem(tr("Automation:"));
2381
menu->insertItem(title, HEADER, HEADER);
2507
//MenuTitleItem* title = new MenuTitleItem(tr("Automation:")); ddskrjo
2508
//menu->insertItem(title, HEADER, HEADER); ddskrjo
2509
menu->addAction(new MenuTitleItem(tr("Automation:"), menu));
2383
2511
//menu->insertSeparator(SEP1);
2385
menu->insertItem(tr("previous event"), PREV_EVENT, PREV_EVENT);
2386
menu->setItemEnabled(PREV_EVENT, canSeekPrev);
2388
menu->insertItem(tr("next event"), NEXT_EVENT, NEXT_EVENT);
2389
menu->setItemEnabled(NEXT_EVENT, canSeekNext);
2391
menu->insertSeparator(SEP2);
2513
QAction* prevEvent = menu->addAction(tr("previous event"));
2514
prevEvent->setData(PREV_EVENT);
2515
prevEvent->setEnabled(canSeekPrev);
2517
QAction* nextEvent = menu->addAction(tr("next event"));
2518
nextEvent->setData(NEXT_EVENT);
2519
nextEvent->setEnabled(canSeekNext);
2521
//menu->insertSeparator(SEP2);
2522
menu->addSeparator();
2524
QAction* addEvent = new QAction(menu);
2525
menu->addAction(addEvent);
2394
menu->insertItem(tr("set event"), ADD_EVENT, ADD_EVENT);
2527
addEvent->setText(tr("set event"));
2396
menu->insertItem(tr("add event"), ADD_EVENT, ADD_EVENT);
2397
menu->setItemEnabled(ADD_EVENT, canAdd);
2398
menu->insertItem(tr("erase event"), CLEAR_EVENT, CLEAR_EVENT);
2399
menu->setItemEnabled(CLEAR_EVENT, isEvent);
2401
menu->insertItem(tr("erase range"), CLEAR_RANGE, CLEAR_RANGE);
2402
menu->setItemEnabled(CLEAR_RANGE, canEraseRange);
2404
menu->insertItem(tr("clear automation"), CLEAR_ALL_EVENTS, CLEAR_ALL_EVENTS);
2405
menu->setItemEnabled(CLEAR_ALL_EVENTS, (bool)count);
2407
int sel = menu->exec(menupos, 1);
2529
addEvent->setText(tr("add event"));
2530
addEvent->setData(ADD_EVENT);
2531
addEvent->setEnabled(canAdd);
2533
QAction* eraseEventAction = menu->addAction(tr("erase event"));
2534
eraseEventAction->setData(CLEAR_EVENT);
2535
eraseEventAction->setEnabled(isEvent);
2537
QAction* eraseRangeAction = menu->addAction(tr("erase range"));
2538
eraseRangeAction->setData(CLEAR_RANGE);
2539
eraseRangeAction->setEnabled(canEraseRange);
2541
QAction* clearAction = menu->addAction(tr("clear automation"));
2542
clearAction->setData(CLEAR_ALL_EVENTS);
2543
clearAction->setEnabled((bool)count);
2545
QAction* act = menu->exec(menupos);
2556
int sel = act->data().toInt();
2416
2561
case ADD_EVENT:
2546
2692
//menu->insertItem(tr("Automation:"), HEADER, HEADER);
2547
2693
//menu->setItemEnabled(HEADER, false);
2548
MenuTitleItem* title = new MenuTitleItem(tr("Automation:"));
2549
menu->insertItem(title, HEADER, HEADER);
2694
//MenuTitleItem* title = new MenuTitleItem(tr("Automation:")); ddskrjo
2695
///menu->insertItem(title, HEADER, HEADER); ddskrjo
2551
2697
//menu->insertSeparator(SEP1);
2559
2705
// menu->insertSeparator(SEP2);
2707
QAction* addEvent = new QAction(menu);
2708
menu->addAction(addEvent);
2562
menu->insertItem(tr("set event"), ADD_EVENT, ADD_EVENT);
2564
menu->insertItem(tr("add event"), ADD_EVENT, ADD_EVENT);
2565
//menu->setItemEnabled(ADD_EVENT, canAdd);
2566
menu->setItemEnabled(ADD_EVENT, true);
2568
menu->insertItem(tr("erase event"), CLEAR_EVENT, CLEAR_EVENT);
2569
menu->setItemEnabled(CLEAR_EVENT, isEvent);
2710
addEvent->setText(tr("set event"));
2712
addEvent->setText(tr("add event"));
2713
addEvent->setData(ADD_EVENT);
2714
//addEvent->setEnabled(canAdd);
2715
addEvent->setEnabled(true);
2717
QAction* eraseEventAction = menu->addAction(tr("erase event"));
2718
eraseEventAction->setData(CLEAR_EVENT);
2719
eraseEventAction->setEnabled(isEvent);
2571
2721
// menu->insertItem(tr("erase range"), CLEAR_RANGE, CLEAR_RANGE);
2572
2722
// menu->setItemEnabled(CLEAR_RANGE, canEraseRange);
2984
//printf("Song::chooseMidiRoutes removing route src track name: %s dst device name: %s\n", track->name().latin1(), md->name().latin1());
3141
//printf("Song::chooseMidiRoutes removing route src track name: %s dst device name: %s\n", track->name().toLatin1().constData(), md->name().toLatin1().constData());
2985
3142
audio->msgRemoveRoute(bRoute, aRoute);
2989
//printf("Song::chooseMidiRoutes removing route src device name: %s dst track name: %s\n", md->name().latin1(), track->name().latin1());
3146
//printf("Song::chooseMidiRoutes removing route src device name: %s dst track name: %s\n", md->name().toLatin1().constData(), track->name().toLatin1().constData());
2990
3147
audio->msgRemoveRoute(aRoute, bRoute);
2998
//printf("Song::chooseMidiRoutes adding route src track name: %s dst device name: %s\n", track->name().latin1(), md->name().latin1());
3155
//printf("Song::chooseMidiRoutes adding route src track name: %s dst device name: %s\n", track->name().toLatin1().constData(), md->name().toLatin1().constData());
2999
3156
audio->msgAddRoute(bRoute, aRoute);
3003
//printf("Song::chooseMidiRoutes adding route src device name: %s dst track name: %s\n", md->name().latin1(), track->name().latin1());
3160
//printf("Song::chooseMidiRoutes adding route src device name: %s dst track name: %s\n", md->name().toLatin1().constData(), track->name().toLatin1().constData());
3004
3161
audio->msgAddRoute(aRoute, bRoute);
3197
3354
const RouteList* rl = track->inRoutes();
3198
3355
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
3200
//printf("Song::insertTrack2 %s in route port:%d\n", track->name().latin1(), r->midiPort); // p3.3.50
3357
//printf("Song::insertTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
3201
3358
Route src(track, r->channel);
3202
3359
midiPorts[r->midiPort].outRoutes()->push_back(src);
3204
3361
rl = track->outRoutes();
3205
3362
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
3207
//printf("Song::insertTrack2 %s out route port:%d\n", track->name().latin1(), r->midiPort); // p3.3.50
3364
//printf("Song::insertTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
3208
3365
Route src(track, r->channel);
3209
3366
midiPorts[r->midiPort].inRoutes()->push_back(src);
3424
3583
const RouteList* rl = track->inRoutes();
3425
3584
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
3427
//printf("Song::removeTrack2 %s in route port:%d\n", track->name().latin1(), r->midiPort); // p3.3.50
3586
//printf("Song::removeTrack2 %s in route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
3428
3587
Route src(track, r->channel);
3429
3588
midiPorts[r->midiPort].outRoutes()->removeRoute(src);
3431
3590
rl = track->outRoutes();
3432
3591
for (ciRoute r = rl->begin(); r != rl->end(); ++r)
3434
//printf("Song::removeTrack2 %s out route port:%d\n", track->name().latin1(), r->midiPort); // p3.3.50
3593
//printf("Song::removeTrack2 %s out route port:%d\n", track->name().toLatin1().constData(), r->midiPort); // p3.3.50
3435
3594
Route src(track, r->channel);
3436
3595
midiPorts[r->midiPort].inRoutes()->removeRoute(src);
3504
3662
song->startUndo(); // undo this entire block
3505
3663
for (iPart i = parts->begin(); i != parts->end(); i++) {
3506
const char* tmp = tmpnam(NULL);
3664
//const char* tmp = tmpnam(NULL);
3665
char tmp[16] = "muse-tmp-XXXXXX";
3666
int fd = mkstemp(tmp);
3507
3667
printf("script input filename=%s\n",tmp);
3508
FILE *fp = fopen(tmp, "w");
3668
//FILE *fp = fopen(tmp, "w");
3669
FILE *fp = fdopen(fd , "w");
3509
3670
MidiPart *part = (MidiPart*)(i->second);
3510
3671
int partStart = part->endTick()-part->lenTick();
3512
sigmap.timesig(0, z, n);
3673
AL::sigmap.timesig(0, z, n);
3513
3674
fprintf(fp, "TIMESIG %d %d\n", z, n);
3514
3675
fprintf(fp, "PART %d %d\n", partStart, part->lenTick());
3515
fprintf(fp, "BEATLEN %d\n", sigmap.ticksBeat(0));
3676
fprintf(fp, "BEATLEN %d\n", AL::sigmap.ticksBeat(0));
3516
3677
fprintf(fp, "QUANTLEN %d\n", quant);
3518
3679
//for (iCItem i = items.begin(); i != items.end(); ++i) {
3565
3726
// TODO: Create a new part, update the entire editor from it, hehh....
3567
3728
QFile file(tmp);
3568
if ( file.open( IO_ReadOnly ) ) {
3729
if ( file.open( QIODevice::ReadOnly ) ) {
3569
3730
QTextStream stream( &file );
3571
3732
while ( !stream.atEnd() ) {
3572
3733
line = stream.readLine(); // line of text excluding '\n'
3573
3734
if (line.startsWith("NOTE"))
3575
QStringList sl = QStringList::split(" ",line);
3736
QStringList sl = line.split(" ");
3578
3739
int tick = sl[1].toInt();
3614
3775
endUndo(SC_EVENT_REMOVED);
3617
#define SCRIPTSSUFFIX "/share/muse/scripts/"
3618
#define USERSCRIPTSSUFFIX "/.muse/scripts/"
3619
void Song::populateScriptMenu(QPopupMenu* menuPlugins, QObject* receiver)
3779
void Song::populateScriptMenu(QMenu* menuPlugins, QObject* receiver)
3622
3782
// List scripts
3624
QString distScripts = QString(INSTPREFIX) + QString(SCRIPTSSUFFIX);
3626
if (getenv("HOME") != NULL)
3627
home = QString(getenv("HOME"));
3628
QString userScripts = home + QString(USERSCRIPTSSUFFIX);
3784
QString distScripts = museGlobalShare + "/scripts";
3786
QString userScripts = configPath + "/scripts";
3630
3788
QFileInfo distScriptsFi(distScripts);
3631
3789
if (distScriptsFi.isDir()) {
3648
3809
for (QStringList::Iterator it = deliveredScriptNames.begin(); it != deliveredScriptNames.end(); it++, id++) {
3649
3810
//menuPlugins->insertItem(*it, this, SLOT(execDeliveredScript(int)), 0, id);
3650
3811
//menuPlugins->insertItem(*it, this, slot_deliveredscripts, 0, id);
3651
menuPlugins->insertItem(*it, receiver, SLOT(execDeliveredScript(int)), 0, id);
3812
QAction* act = menuPlugins->addAction(*it);
3813
connect(act, SIGNAL(triggered()), distSignalMapper, SLOT(map()));
3814
distSignalMapper->setMapping(act, id);
3653
menuPlugins->insertSeparator();
3816
menuPlugins->addSeparator();
3655
3818
if (userScriptNames.size() > 0) {
3656
3819
for (QStringList::Iterator it = userScriptNames.begin(); it != userScriptNames.end(); it++, id++) {
3657
3820
//menuPlugins->insertItem(*it, this, slot_userscripts, 0, id);
3658
menuPlugins->insertItem(*it, receiver, SLOT(execUserScript(int)), 0, id);
3821
QAction* act = menuPlugins->addAction(*it);
3822
connect(act, SIGNAL(triggered()), userSignalMapper, SLOT(map()));
3823
userSignalMapper->setMapping(act, id);
3660
menuPlugins->insertSeparator();
3825
menuPlugins->addSeparator();
3827
connect(distSignalMapper, SIGNAL(mapped(int)), receiver, SLOT(execDeliveredScript(int)));
3828
connect(userSignalMapper, SIGNAL(mapped(int)), receiver, SLOT(execUserScript(int)));