Mercurial > hg > dmlib
view editor/edmain.cpp @ 2576:812b16ee49db
I had been living under apparent false impression that "realfft.c"
on which the FFT implementation in DMLIB was basically copied from
was released in public domain at some point, but it could very well
be that it never was. Correct license is (or seems to be) GNU GPL.
Thus I removing the code from DMLIB, and profusely apologize to the
author, Philip Van Baren.
It was never my intention to distribute code based on his original
work under a more liberal license than originally intended.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 11 Mar 2022 16:32:50 +0200 |
parents | 69a5af2eb1ea |
children |
line wrap: on
line source
// // Demo Editor -- Main program // (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> // #include <SDL.h> #include "dmengine.h" #include "edmain.h" #include <QSettings> #include <QGLWidget> int main(int argc, char *argv[]) { dmVerbosity = 5; QApplication app(argc, argv); app.setOrganizationName("TNSP"); app.setOrganizationDomain("tnsp.org"); app.setApplicationName(PROGRAM_NAME); app.setApplicationVersion(PROGRAM_VERSION); DemoEditor mainWin; mainWin.show(); return app.exec(); } void engineAudioCallback(void *userdata, Uint8 * stream, int len) { DMEngineData *engine = (DMEngineData *) userdata; if (engine->paused) { memset(stream, 0, len); } else #ifdef DM_USE_JSS { if (engine->jssDev != NULL) jvmRenderAudio(engine->jssDev, stream, len / jvmGetSampleSize(engine->jssDev)); } #endif #ifdef DM_USE_TREMOR if (engine->audioPos + len >= engine->audioRes->resSize) { engine->exitFlag = true; } else { memcpy(stream, (Uint8 *) engine->audioRes->resData + engine->audioPos, len); engine->audioPos += len; } #endif } int DemoEditor::reopenResources() { int err; if ((err = dmResourcesInit( &engine.resources, engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) { dmErrorMsg("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); } return err; } int DemoEditor::loadResources() { int err, loaded = 0, total = 0; BOOL first = TRUE; do { /* // Show a nice progress bar while loading if ((err = engineShowProgress(loaded, total)) != DMERR_OK) return err; */ err = dmResourcesPreload(engine.resources, first, &loaded, &total); first = FALSE; } while (err == DMERR_PROGRESS); return DMERR_OK; } DemoEditor::DemoEditor() { int err; resize(1024, 768); setWindowTitle(QCoreApplication::applicationName()); memset(&engine, 0, sizeof(engine)); initSDL = FALSE; currTimeline = NULL; // Pre-initialization if ((err = demoPreInit(&engine)) != DMERR_OK) goto error_exit; // Initialize SDL components dmPrint(1, "Initializing libSDL.\n"); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) != 0) { dmErrorMsg("Could not initialize SDL: %s\n", SDL_GetError()); goto error_exit; } initSDL = true; // Initialize audio parts if (engine.optAfmt.freq == 0 && engine.optAfmt.channels == 0) { // Defaults, if none seem to be set engine.optAfmt.freq = 44100; engine.optAfmt.format = AUDIO_S16SYS; engine.optAfmt.channels = 2; engine.optAfmt.samples = engine.optAfmt.freq / 16; } #ifdef DM_USE_JSS jssInit(); switch (engine.optAfmt.format) { case AUDIO_S16SYS: engine.jssFormat = JSS_AUDIO_S16; break; case AUDIO_U16SYS: engine.jssFormat = JSS_AUDIO_U16; break; case AUDIO_S8: engine.jssFormat = JSS_AUDIO_S8; break; case AUDIO_U8: engine.jssFormat = JSS_AUDIO_U8; break; } dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", engine.jssFormat, engine.optAfmt.channels, engine.optAfmt.freq); if ((engine.jssDev = jvmInit(engine.jssFormat, engine.optAfmt.channels, engine.optAfmt.freq, JMIX_AUTO)) == NULL) { dmErrorMsg("jvmInit() returned NULL, voi perkele.\n"); goto error_exit; } if ((engine.jssPlr = jmpInit(engine.jssDev)) == NULL) { dmErrorMsg("jmpInit() returned NULL\n"); goto error_exit; } #endif // Initialize SDL audio dmPrint(1, "Trying to init SDL audio with: fmt=%d, chn=%d, freq=%d\n", engine.optAfmt.format, engine.optAfmt.channels, engine.optAfmt.freq); engine.optAfmt.callback = engineAudioCallback; if (SDL_OpenAudio(&engine.optAfmt, NULL) < 0) { dmErrorMsg("Couldn't open SDL audio: %s\n", SDL_GetError()); goto error_exit; } // Initialize SDL video if (engine.demoInitPreVideo != NULL && (err = engine.demoInitPreVideo(&engine)) != DMERR_OK) { dmErrorMsg("demoInitPreVideo() failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } dmPrint(1, "Initializing SDL video %d x %d x %dbpp, flags=0x%08x\n", engine.optVidWidth, engine.optVidHeight, engine.optVidDepth, engine.optVFlags); engine.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, engine.optVidWidth, engine.optVidHeight, engine.optVidDepth, 0, 0, 0, 0); if (engine.screen == NULL) { dmErrorMsg("Could not allocate video backbuffer surface.\n"); goto error_exit; } if (engine.demoInitPostVideo != NULL && (err = engine.demoInitPostVideo(&engine)) != DMERR_OK) { dmErrorMsg("demoInitPostVideo() failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } error_exit: // Setup GUI elements createMainGUI(); createNewFile(); timelineView->setTimeline(currTimeline); settingsRestore(); initEffectsAndResources(); statusMsg("Application started."); } DemoEditor::~DemoEditor() { statusMsg("Shutting down."); settingsSave(); delete demoView; historyReset(); if (engine.screen) SDL_FreeSurface(engine.screen); SDL_LockAudio(); SDL_PauseAudio(1); #ifdef DM_USE_JSS jmpClose(engine.jssPlr); jvmClose(engine.jssDev); jssClose(); #endif SDL_UnlockAudio(); shutdownEffectsAndResources(); if (initSDL) SDL_Quit(); } int DemoEditor::getTimelineDuration() { return timelineAudioTrack->getDuration(); } void DemoEditor::updateResourceView() { } void DemoEditor::updateTimelineView() { demoView->setEngineData(&engine); if (engine.audioRes != NULL) { timelineAudioTrack->setWaveform( engine.audioRes->resData, engine.audioRes->resSize, engine.optAfmt.format, engine.optAfmt.channels, engine.optAfmt.freq); } timelineAudioTrack->setOffset(currViewOffset); timelineAudioTrack->setScale(currViewScale); timelineView->setTime(currFrameTime); timelineView->setOffset(currViewOffset); timelineView->setScale(currViewScale); timelineScrollBar->setRange(0, getTimelineDuration()); timelineScrollBar->setValue(currViewOffset); } void DemoEditor::actionTimelineScrollChanged(int value) { currViewOffset = value; updateTimelineView(); } void DemoEditor::actionOffsetChanged(float value) { currViewOffset = value; updateTimelineView(); } void DemoEditor::actionTimeChanged(float value) { currFrameTime = value; updateTimelineView(); } void DemoEditor::actionTimelineChanged() { updateMenuStates(); update(); } int DemoEditor::initEffectsAndResources() { int err; currViewOffset = 0; currFrameTime = 0; currViewScale = 1.0f; // Initialize resource subsystem statusMsg("Initializing resources subsystem."); if ((err = reopenResources()) != DMERR_OK) return err; // Load resources statusMsg("Loading resources, please wait..."); if ((err = loadResources()) != DMERR_OK) { dmErrorMsg("Error loading resources, %d: %s.\n", err, dmErrorStr(err)); return err; } // Final initializations statusMsg("Initializing custom demo data."); if ((err = engine.demoInit(&engine)) != DMERR_OK) { dmErrorMsg("Failure in demoInit(), %d: %s\n", err, dmErrorStr(err)); return err; } // Initialize effects statusMsg("Initializing effects ..."); if ((err = engineInitializeEffects(&engine)) != DMERR_OK) { dmErrorMsg("Effects initialization failed, %d: %s\n", err, dmErrorStr(err)); return err; } // Etc. rehash(); return DMERR_OK; } void DemoEditor::shutdownEffectsAndResources() { delete currTimeline; dmFreePreparedTimelineData(engine.ptl); engineShutdownEffects(&engine); dmResourcesClose(engine.resources); if (engine.demoShutdown != NULL) engine.demoShutdown(&engine); } void DemoEditor::rehash() { timelineView->setTimeline(currTimeline); updateResourceView(); updateTimelineView(); updateMenuStates(); update(); } void DemoEditor::createNewFile() { delete currTimeline; currTimeline = new EDTimelineObject(); DMTimelineTrack *tr; dmTimelineAddTrack(currTimeline->tl, &tr, "Penis"); DMTimelineEvent *ev; dmTimelineTrackAddEvent(tr, 500, 100, &ev); dmTimelineEventSetEffectByIndex(ev, 0); historyReset(); updateMenuStates(); update(); } void DemoEditor::readFromFile(QString filename) { EDTimelineObject *tmp = new EDTimelineObject(); int ret = tmp->load(filename); if (ret != DMERR_OK) { showFileErrorDialog("Loading demo blob file "+ filename, ret); delete tmp; } else { delete currTimeline; currTimeline = tmp; rehash(); } } void DemoEditor::saveToFile(QString filename) { int ret = currTimeline->save(filename); if (ret != DMERR_OK) { showFileErrorDialog("Saving demo blob file "+ filename, ret); } updateMenuStates(); } void DemoEditor::settingsRestore() { QSettings s; restoreGeometry(s.value("windowGeometry").toByteArray()); restoreState(s.value("windowState").toByteArray()); } void DemoEditor::settingsSave() { QSettings s; s.setValue("windowGeometry", saveGeometry()); s.setValue("windowState", saveState()); } // // Edit history functionality // void DemoEditor::historyReset() { if (currTimeline != NULL) currTimeline->scrub(); undoHistoryPos = -1; undoHistoryMax = DOC_UNDO_MAX; undoHistory.clear(); } void DemoEditor::historyPush(QString description) { if (currTimeline == NULL) return; if (!undoHistory.isEmpty() && undoHistory.last()->state() == "-") { delete undoHistory.takeLast(); } while (undoHistory.size() >= undoHistoryMax) { delete undoHistory.takeFirst(); } EDTimelineObject *copy = new EDTimelineObject(currTimeline); copy->setState(description); undoHistory.append(copy); } void DemoEditor::historyTop() { if (currTimeline == NULL) return; EDTimelineObject *copy = new EDTimelineObject(currTimeline); copy->setState("-"); undoHistory.append(copy); undoHistoryPos = undoHistory.size() - 1; currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } void DemoEditor::historyPop() { if (!undoHistory.isEmpty()) { delete undoHistory.takeLast(); } } void DemoEditor::performRedo() { if (undoHistoryPos >= 0 && undoHistoryPos < undoHistory.size() - 1) { undoHistoryPos++; delete currTimeline; currTimeline = new EDTimelineObject(undoHistory.at(undoHistoryPos)); currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } } void DemoEditor::performUndo() { if (undoHistoryPos > 0 && undoHistory.size() > 1) { undoHistoryPos--; delete currTimeline; currTimeline = new EDTimelineObject(undoHistory.at(undoHistoryPos)); currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } }