void CueStack_Test::nextPrevious() { CueStack cs(m_doc); QCOMPARE(cs.previous(), -1); QCOMPARE(cs.next(), -1); cs.appendCue(Cue("One")); QCOMPARE(cs.previous(), 0); QCOMPARE(cs.next(), 0); cs.appendCue(Cue("Two")); QCOMPARE(cs.previous(), 1); QCOMPARE(cs.next(), 0); QCOMPARE(cs.next(), 1); QCOMPARE(cs.next(), 0); QCOMPARE(cs.previous(), 1); QCOMPARE(cs.previous(), 0); cs.appendCue(Cue("Three")); QCOMPARE(cs.next(), 1); QCOMPARE(cs.next(), 2); QCOMPARE(cs.next(), 0); QCOMPARE(cs.previous(), 2); QCOMPARE(cs.previous(), 1); QCOMPARE(cs.previous(), 0); }
void CueStack_Test::appendCue() { CueStack cs(m_doc); QCOMPARE(cs.cues().size(), 0); cs.appendCue(Cue("One")); QCOMPARE(cs.cues().size(), 1); QCOMPARE(cs.cues().at(0).name(), QString("One")); cs.appendCue(Cue("Two")); QCOMPARE(cs.cues().size(), 2); QCOMPARE(cs.cues().at(0).name(), QString("One")); QCOMPARE(cs.cues().at(1).name(), QString("Two")); cs.appendCue(Cue("Three")); QCOMPARE(cs.cues().size(), 3); QCOMPARE(cs.cues().at(0).name(), QString("One")); QCOMPARE(cs.cues().at(1).name(), QString("Two")); QCOMPARE(cs.cues().at(2).name(), QString("Three")); cs.appendCue(Cue("Four")); QCOMPARE(cs.cues().size(), 4); QCOMPARE(cs.cues().at(0).name(), QString("One")); QCOMPARE(cs.cues().at(1).name(), QString("Two")); QCOMPARE(cs.cues().at(2).name(), QString("Three")); QCOMPARE(cs.cues().at(3).name(), QString("Four")); }
void CueStack_Test::removeCue() { CueStack cs(m_doc); cs.appendCue(Cue("One")); cs.appendCue(Cue("Two")); cs.appendCue(Cue("Three")); cs.appendCue(Cue("Four")); cs.appendCue(Cue("Five")); QCOMPARE(cs.cues().size(), 5); cs.setCurrentIndex(4); cs.removeCue(-1); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.currentIndex(), 4); cs.removeCue(5); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.currentIndex(), 4); cs.removeCue(3); QCOMPARE(cs.cues().size(), 4); QCOMPARE(cs.currentIndex(), 3); // currentIndex-- because a cue before it was removed QCOMPARE(cs.cues().at(0).name(), QString("One")); QCOMPARE(cs.cues().at(1).name(), QString("Two")); QCOMPARE(cs.cues().at(2).name(), QString("Three")); QCOMPARE(cs.cues().at(3).name(), QString("Five")); cs.removeCue(0); QCOMPARE(cs.cues().size(), 3); QCOMPARE(cs.currentIndex(), 2); // currentIndex-- because a cue before it was removed QCOMPARE(cs.cues().at(0).name(), QString("Two")); QCOMPARE(cs.cues().at(1).name(), QString("Three")); QCOMPARE(cs.cues().at(2).name(), QString("Five")); cs.setCurrentIndex(0); cs.removeCue(2); QCOMPARE(cs.cues().size(), 2); QCOMPARE(cs.currentIndex(), 0); // no change because a cue AFTER it was removed QCOMPARE(cs.cues().at(0).name(), QString("Two")); QCOMPARE(cs.cues().at(1).name(), QString("Three")); cs.removeCue(2); QCOMPARE(cs.cues().size(), 2); QCOMPARE(cs.currentIndex(), 0); // no change because nothing was removed QCOMPARE(cs.cues().at(0).name(), QString("Two")); QCOMPARE(cs.cues().at(1).name(), QString("Three")); cs.removeCue(0); QCOMPARE(cs.cues().size(), 1); QCOMPARE(cs.currentIndex(), 0); // currentIndex was removed -> next cue becomes current QCOMPARE(cs.cues().at(0).name(), QString("Three")); cs.removeCue(0); QCOMPARE(cs.cues().size(), 0); cs.removeCue(0); QCOMPARE(cs.cues().size(), 0); }
void CueStack_Test::save() { CueStack cs(m_doc); cs.appendCue(Cue("One")); cs.appendCue(Cue("Two")); cs.appendCue(Cue("Three")); cs.setFadeInSpeed(200); cs.setFadeOutSpeed(300); cs.setDuration(400); QDomDocument doc; QDomElement root = doc.createElement("Foo"); doc.appendChild(root); QCOMPARE(cs.saveXML(&doc, &root, 42), true); QCOMPARE(root.firstChild().toElement().tagName(), QString("CueStack")); int cue = 0, speed = 0; QDomNode node = root.firstChild().firstChild(); while (node.isNull() == false) { QDomElement tag = node.toElement(); if (tag.tagName() == "Speed") { speed++; QCOMPARE(tag.attribute("FadeIn"), QString("200")); QCOMPARE(tag.attribute("FadeOut"), QString("300")); QCOMPARE(tag.attribute("Duration"), QString("400")); } else if (tag.tagName() == "Cue") { // The contents of a Cue tag are tested in Cue tests cue++; } else { QFAIL(QString("Unexpected tag: %1").arg(tag.tagName()).toUtf8().constData()); } node = node.nextSibling(); } QCOMPARE(cue, 3); QCOMPARE(speed, 1); }
void CueStack_Test::write() { QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); CueStack cs(m_doc); Cue cue("One"); cue.setValue(0, 255); cue.setFadeInSpeed(100); cue.setFadeOutSpeed(200); cue.setDuration(300); cs.appendCue(cue); cue = Cue("Two"); cue.setValue(1, 255); cue.setFadeInSpeed(100); cue.setFadeOutSpeed(200); cue.setDuration(300); cs.appendCue(cue); cs.preRun(); QVERIFY(cs.m_fader != NULL); cs.write(ua); QCOMPARE(cs.currentIndex(), -1); cs.start(); cs.write(ua); QCOMPARE(cs.currentIndex(), -1); cs.nextCue(); QCOMPARE(cs.currentIndex(), -1); cs.write(ua); QCOMPARE(cs.currentIndex(), 0); QCOMPARE(cs.m_fader->channels().size(), 1); FadeChannel fc; fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); cs.previousCue(); QCOMPARE(cs.currentIndex(), 0); cs.write(ua); QCOMPARE(cs.currentIndex(), 1); fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(0)); fc.setChannel(1); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(1)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); MasterTimer mt(m_doc); cs.postRun(&mt); }
void CueStack_Test::replaceCue() { CueStack cs(m_doc); QCOMPARE(cs.cues().size(), 0); cs.appendCue(Cue("One")); cs.appendCue(Cue("Two")); cs.appendCue(Cue("Three")); cs.appendCue(Cue("Four")); cs.appendCue(Cue("Five")); QCOMPARE(cs.cues().size(), 5); cs.replaceCue(0, Cue("Six")); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.cues()[0].name(), QString("Six")); QCOMPARE(cs.cues()[1].name(), QString("Two")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.cues()[3].name(), QString("Four")); QCOMPARE(cs.cues()[4].name(), QString("Five")); cs.replaceCue(-1, Cue("Seven")); QCOMPARE(cs.cues().size(), 6); QCOMPARE(cs.cues()[0].name(), QString("Six")); QCOMPARE(cs.cues()[1].name(), QString("Two")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.cues()[3].name(), QString("Four")); QCOMPARE(cs.cues()[4].name(), QString("Five")); QCOMPARE(cs.cues()[5].name(), QString("Seven")); cs.replaceCue(20, Cue("Eight")); QCOMPARE(cs.cues().size(), 7); QCOMPARE(cs.cues()[0].name(), QString("Six")); QCOMPARE(cs.cues()[1].name(), QString("Two")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.cues()[3].name(), QString("Four")); QCOMPARE(cs.cues()[4].name(), QString("Five")); QCOMPARE(cs.cues()[5].name(), QString("Seven")); QCOMPARE(cs.cues()[6].name(), QString("Eight")); cs.replaceCue(5, Cue("Nine")); QCOMPARE(cs.cues().size(), 7); QCOMPARE(cs.cues()[0].name(), QString("Six")); QCOMPARE(cs.cues()[1].name(), QString("Two")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.cues()[3].name(), QString("Four")); QCOMPARE(cs.cues()[4].name(), QString("Five")); QCOMPARE(cs.cues()[5].name(), QString("Nine")); QCOMPARE(cs.cues()[6].name(), QString("Eight")); }
void CueStack_Test::removeCues() { CueStack cs(m_doc); cs.appendCue(Cue("One")); cs.appendCue(Cue("Two")); cs.appendCue(Cue("Three")); cs.appendCue(Cue("Four")); cs.appendCue(Cue("Five")); QCOMPARE(cs.cues().size(), 5); cs.setCurrentIndex(4); cs.removeCues(QList <int>()); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.currentIndex(), 4); cs.removeCues(QList <int>() << 5); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.currentIndex(), 4); cs.removeCues(QList <int>() << 3); QCOMPARE(cs.cues().size(), 4); QCOMPARE(cs.currentIndex(), 3); // currentIndex-- because a cue before it was removed QCOMPARE(cs.cues().at(0).name(), QString("One")); QCOMPARE(cs.cues().at(1).name(), QString("Two")); QCOMPARE(cs.cues().at(2).name(), QString("Three")); QCOMPARE(cs.cues().at(3).name(), QString("Five")); cs.removeCues(QList <int>() << 2 << 0); QCOMPARE(cs.cues().size(), 2); QCOMPARE(cs.currentIndex(), 1); // currentIndex-- times two because two cue before it were removed QCOMPARE(cs.cues().at(0).name(), QString("Two")); QCOMPARE(cs.cues().at(1).name(), QString("Five")); cs.removeCues(QList <int>() << 0 << 1); QCOMPARE(cs.cues().size(), 0); QCOMPARE(cs.currentIndex(), 0); cs.removeCues(QList <int>() << 0 << 100 << 1000); QCOMPARE(cs.cues().size(), 0); }
// Play void AudioStream::Play (long volume, int looping) { if (m_pdsb) { // If playing, stop if (m_fPlaying) { if ( m_bIsPaused == FALSE) Stop_and_Rewind(); } // Cue for playback if necessary if (!m_fCued) { Cue (); } if ( looping ) m_bLooping = 1; else m_bLooping = 0; // Begin DirectSound playback HRESULT hr = m_pdsb->Play (0, 0, DSBPLAY_LOOPING); if (hr == DS_OK) { m_nTimeStarted = timer_get_milliseconds(); Set_Volume(volume); // Kick off timer to service buffer m_timer.constructor(); m_timer.Create (m_nBufService, m_nBufService, DWORD (this), TimerCallback); // Playback begun, no longer cued m_fPlaying = TRUE; m_bIsPaused = FALSE; } else { // If the buffer was lost, try to restore it if ( hr == DSERR_BUFFERLOST ) { hr = m_pdsb->Restore(); if ( hr == DS_OK ) { hr = m_pdsb->Play (0, 0, DSBPLAY_LOOPING); } else { nprintf(("Sound", "Sound => Lost a buffer, tried restoring but got %s\n", get_DSERR_text(hr) )); Int3(); // get Alan, he wants to see this } } if ( hr != DS_OK ) { nprintf(("Sound", "Sound => Play failed with return value %s\n", get_DSERR_text(hr) )); } } } }
Cue ParseCue (const QString& cue) { QFile file (cue); if (!file.open (QIODevice::ReadOnly)) { qWarning () << Q_FUNC_INFO << "unable to parse" << cue; return Cue (); } Cue result; const auto& lines = file.readAll ().split ('\n'); for (auto i = lines.begin (), end= lines.end (); i != end; ) { const auto& line = i->trimmed (); if (line.startsWith ("REM ")) { HandleREM (line, result); ++i; } else if (line.startsWith ("PERFORMER ")) { result.Performer_ = ChopQuotes (QString::fromUtf8 (line.mid (10))); ++i; } else if (line.startsWith ("TITLE ")) { result.Album_ = ChopQuotes (QString::fromUtf8 (line.mid (6))); ++i; } else if (line.startsWith ("FILE ")) i = HandleFile (line.mid (5), i + 1, end, result); } return result; }
void CueStack_Test::currentIndex() { CueStack cs(m_doc); cs.appendCue(Cue("One")); cs.appendCue(Cue("Two")); cs.appendCue(Cue("Three")); cs.appendCue(Cue("Four")); cs.appendCue(Cue("Five")); cs.setCurrentIndex(-1); QCOMPARE(cs.currentIndex(), -1); cs.setCurrentIndex(-2); QCOMPARE(cs.currentIndex(), -1); cs.setCurrentIndex(1); QCOMPARE(cs.currentIndex(), 1); cs.setCurrentIndex(2); QCOMPARE(cs.currentIndex(), 2); cs.setCurrentIndex(4); QCOMPARE(cs.currentIndex(), 4); cs.setCurrentIndex(3); QCOMPARE(cs.currentIndex(), 3); cs.setCurrentIndex(5); QCOMPARE(cs.currentIndex(), 4); cs.setCurrentIndex(-1); QCOMPARE(cs.currentIndex(), -1); cs.nextCue(); QCOMPARE(cs.m_previous, false); QCOMPARE(cs.m_next, true); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(cs.isRunning(), true); QCOMPARE(cs.isStarted(), false); cs.nextCue(); QCOMPARE(cs.m_previous, false); QCOMPARE(cs.m_next, true); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(cs.isRunning(), true); QCOMPARE(cs.isStarted(), false); cs.m_running = false; cs.m_next = false; cs.previousCue(); QCOMPARE(cs.m_previous, true); QCOMPARE(cs.m_next, false); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(cs.isRunning(), true); QCOMPARE(cs.isStarted(), false); cs.previousCue(); QCOMPARE(cs.m_previous, true); QCOMPARE(cs.m_next, false); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(cs.isRunning(), true); QCOMPARE(cs.isStarted(), false); }
void CueStack_Test::postRun() { QLCFixtureDef* def = m_doc->fixtureDefCache()->fixtureDef("Futurelight", "DJScan250"); QVERIFY(def != NULL); QLCFixtureMode* mode = def->modes().first(); QVERIFY(mode != NULL); Fixture* fxi = new Fixture(m_doc); fxi->setFixtureDefinition(def, mode); fxi->setName("Test Scanner"); fxi->setAddress(10); fxi->setUniverse(0); m_doc->addFixture(fxi); MasterTimer mt(m_doc); QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); CueStack cs(m_doc); cs.setFadeInSpeed(100); cs.setFadeOutSpeed(200); cs.setDuration(300); Cue cue; cue.setName("One"); cue.setValue(0, 255); cue.setValue(1, 255); cue.setValue(500, 255); cue.setValue(10, 255); // LTP cue.setValue(11, 255); // LTP cs.appendCue(cue); cue = Cue(); cue.setName("Two"); cue.setValue(500, 255); cue.setValue(3, 255); cue.setValue(4, 255); cue.setValue(11, 255); // LTP cs.appendCue(cue); cs.preRun(); // Switch to cue one cs.switchCue(-1, 0, ua); QCOMPARE(cs.m_fader->channels().size(), 5); QSignalSpy cueSpy(&cs, SIGNAL(currentCueChanged(int))); QSignalSpy stopSpy(&cs, SIGNAL(stopped())); cs.postRun(&mt); QCOMPARE(cs.m_fader, (GenericFader*) NULL); QCOMPARE(cs.m_currentIndex, -1); QCOMPARE(cueSpy.size(), 1); QCOMPARE(cueSpy.at(0).size(), 1); QCOMPARE(cueSpy.at(0).at(0).toInt(), -1); QCOMPARE(stopSpy.size(), 1); // Only HTP channels go to MasterTimer's GenericFader QCOMPARE(mt.m_fader->channels().size(), 3); FadeChannel fc; fc.setChannel(0); QCOMPARE(mt.m_fader->channels().contains(fc), true); fc.setChannel(1); QCOMPARE(mt.m_fader->channels().contains(fc), true); fc.setChannel(500); QCOMPARE(mt.m_fader->channels().contains(fc), true); }
// Open BOOL WaveFile::Open (LPSTR pszFilename) { int done = FALSE; WORD cbExtra = 0; BOOL fRtn = SUCCESS; // assume success PCMWAVEFORMAT pcmwf; char fullpath[_MAX_PATH]; m_total_uncompressed_bytes_read = 0; m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX; int FileSize, FileOffset; if ( !cf_find_file_location(pszFilename, CF_TYPE_ANY, fullpath, &FileSize, &FileOffset )) { goto OPEN_ERROR; } cfp = mmioOpen(fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ); if ( cfp == NULL ) { goto OPEN_ERROR; } // Skip the "RIFF" tag and file size (8 bytes) // Skip the "WAVE" tag (4 bytes) mmioSeek( cfp, 12+FileOffset, SEEK_SET ); // Now read RIFF tags until the end of file uint tag, size, next_chunk; while(done == FALSE) { if ( mmioRead(cfp, (char *)&tag, sizeof(uint)) != sizeof(uint) ) break; if ( mmioRead(cfp, (char *)&size, sizeof(uint)) != sizeof(uint) ) break; next_chunk = mmioSeek( cfp, 0, SEEK_CUR ); next_chunk += size; switch( tag ) { case 0x20746d66: // The 'fmt ' tag mmioRead( cfp, (char *)&pcmwf, sizeof(PCMWAVEFORMAT) ); if ( pcmwf.wf.wFormatTag != WAVE_FORMAT_PCM ) { mmioRead( cfp, (char *)&cbExtra, sizeof(short) ); } // Allocate memory for WAVEFORMATEX structure + extra bytes if ( (m_pwfmt_original = (WAVEFORMATEX *) malloc ( sizeof(WAVEFORMATEX)+cbExtra )) != NULL ){ Assert(m_pwfmt_original != NULL); // Copy bytes from temporary format structure memcpy (m_pwfmt_original, &pcmwf, sizeof(pcmwf)); m_pwfmt_original->cbSize = cbExtra; // Read those extra bytes, append to WAVEFORMATEX structure if (cbExtra != 0) { mmioRead( cfp, (char *)((ubyte *)(m_pwfmt_original) + sizeof(WAVEFORMATEX)), cbExtra ); } } else { Int3(); // malloc failed goto OPEN_ERROR; } break; case 0x61746164: // the 'data' tag m_nDataSize = size; // This is size of data chunk. Compressed if ADPCM. m_data_bytes_left = size; m_data_offset = mmioSeek( cfp, 0, SEEK_CUR); done = TRUE; break; default: // unknown, skip it break; } // end switch mmioSeek( cfp, next_chunk, SEEK_SET ); } // At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound. // Since DirectSound only supports PCM, force this structure to be PCM compliant. We will // need to convert data on the fly later if our souce is not PCM switch ( m_pwfmt_original->wFormatTag ) { case WAVE_FORMAT_PCM: m_wave_format = WAVE_FORMAT_PCM; m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample; break; case WAVE_FORMAT_ADPCM: m_wave_format = WAVE_FORMAT_ADPCM; m_wfmt.wBitsPerSample = 16; break; default: nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n")); //Int3(); goto OPEN_ERROR; break; } // end switch // Set up the WAVEFORMATEX structure to have the right PCM characteristics m_wfmt.wFormatTag = WAVE_FORMAT_PCM; m_wfmt.nChannels = m_pwfmt_original->nChannels; m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec; m_wfmt.cbSize = 0; m_wfmt.nBlockAlign = (unsigned short)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8); m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec; // Init some member data from format chunk m_nBlockAlign = m_pwfmt_original->nBlockAlign; m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec; // Cue for streaming Cue (); // Successful open goto OPEN_DONE; OPEN_ERROR: // Handle all errors here nprintf(("SOUND","SOUND ==> Could not open wave file %s for streaming\n",pszFilename)); fRtn = FAILURE; if (cfp != NULL) { // Close file mmioClose( cfp, 0 ); cfp = NULL; } if (m_pwfmt_original) { free(m_pwfmt_original); m_pwfmt_original = NULL; } OPEN_DONE: return (fRtn); }
// Create BOOL AudioStream::Create (LPSTR pszFilename, AudioStreamServices * pass) { BOOL fRtn = SUCCESS; // assume success Assert(pszFilename); Assert(pass); m_pass = pass; Init_Data(); if (pszFilename && m_pass) { // Create a new WaveFile object m_pwavefile = (WaveFile *)malloc(sizeof(WaveFile)); Assert(m_pwavefile); if (m_pwavefile) { // Call constructor m_pwavefile->Init(); // Open given file m_pwavefile->m_bits_per_sample_uncompressed = m_bits_per_sample_uncompressed; if (m_pwavefile->Open (pszFilename)) { // Calculate sound buffer size in bytes // Buffer size is average data rate times length of buffer // No need for buffer to be larger than wave data though m_cbBufSize = (m_pwavefile->GetUncompressedAvgDataRate () * m_nBufLength) / 1000; nprintf(("SOUND", "SOUND => Stream buffer created using %d bytes\n", m_cbBufSize)); // m_cbBufSize = (m_cbBufSize > m_pwavefile->GetDataSize ()) ? m_pwavefile->GetDataSize () : m_cbBufSize; //nprintf(("Sound", "SOUND => average data rate = %d\n\r", m_pwavefile->GetUncompressedAvgDataRate ())); //nprintf(("Sound", "SOUND => m_cbBufSize = %d\n\r", m_cbBufSize)); // Create sound buffer HRESULT hr; memset (&m_dsbd, 0, sizeof (DSBUFFERDESC)); m_dsbd.dwSize = sizeof (DSBUFFERDESC); m_dsbd.dwBufferBytes = m_cbBufSize; m_dsbd.lpwfxFormat = &m_pwavefile->m_wfmt; m_dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_LOCSOFTWARE; hr = (m_pass->GetPDS ())->CreateSoundBuffer (&m_dsbd, &m_pdsb, NULL); if (hr == DS_OK) { // Cue for playback Cue (); Snd_sram += m_cbBufSize; } else { // Error, unable to create DirectSound buffer nprintf(("Sound", "SOUND => Error, unable to create DirectSound buffer\n\r")); if (hr == DSERR_BADFORMAT) { nprintf(("Sound", "SOUND => Bad format (probably ADPCM)\n\r")); } fRtn = FAILURE; } } else { // Error opening file nprintf(("SOUND", "SOUND => Failed to open wave file: %s\n\r", pszFilename)); m_pwavefile->Close(); free(m_pwavefile); m_pwavefile = NULL; fRtn = FAILURE; } } else { // Error, unable to create WaveFile object nprintf(("Sound", "SOUND => Failed to create WaveFile object %s\n\r", pszFilename)); fRtn = FAILURE; } } else { // Error, passed invalid parms fRtn = FAILURE; } return (fRtn); }
// Open BOOL WaveFile::Open (LPSTR pszFilename) { WORD cbExtra = 0; DOUT ("WaveFile::Open\n\r"); BOOL fRtn = SUCCESS; // assume success // Open the requested file if ((m_hmmio = mmioOpen (pszFilename, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL) { m_mmr = MMIOERR_CANNOTOPEN; goto OPEN_ERROR; } // Descend into initial chunk ('RIFF') if (m_mmr = mmioDescend (m_hmmio, &m_mmckiRiff, NULL, 0)) { goto OPEN_ERROR; } // Validate that it's a WAVE file if ((m_mmckiRiff.ckid != FOURCC_RIFF) || (m_mmckiRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) { m_mmr = MMIOERR_INVALIDFILE; goto OPEN_ERROR; } // Find format chunk ('fmt '), allocate and fill WAVEFORMATEX structure m_mmckiFmt.ckid = mmioFOURCC('f', 'm', 't', ' '); if (m_mmr = mmioDescend (m_hmmio, &m_mmckiFmt, &m_mmckiRiff, MMIO_FINDCHUNK)) { goto OPEN_ERROR; } // Read the format chunk into temporary structure PCMWAVEFORMAT pcmwf; if (mmioRead (m_hmmio, (CHAR *) &pcmwf, sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT)) { m_mmr = MMIOERR_CANNOTREAD; goto OPEN_ERROR; } // If format is not PCM, then there are extra bytes appended to WAVEFORMATEX if (pcmwf.wf.wFormatTag != WAVE_FORMAT_PCM) { // Read WORD specifying number of extra bytes if (mmioRead (m_hmmio, (LPSTR) &cbExtra, sizeof (cbExtra)) != sizeof(cbExtra)) { m_mmr = MMIOERR_CANNOTREAD; goto OPEN_ERROR; } } // Allocate memory for WAVEFORMATEX structure + extra bytes // UNDONE: GMEM_FIXED???? use malloc? if (m_pwfmt = (WAVEFORMATEX *) GlobalAlloc (GMEM_FIXED, sizeof(WAVEFORMATEX)+cbExtra)) { // Copy bytes from temporary format structure memcpy (m_pwfmt, &pcmwf, sizeof(pcmwf)); m_pwfmt->cbSize = cbExtra; // Read those extra bytes, append to WAVEFORMATEX structure if (cbExtra != 0) { if ((m_mmr = mmioRead (m_hmmio, (LPSTR) ((BYTE *)(m_pwfmt) + sizeof (WAVEFORMATEX)), cbExtra)) != cbExtra) { // Error reading extra bytes m_mmr = MMIOERR_CANNOTREAD; goto OPEN_ERROR; } } } else { // Error allocating memory m_mmr = MMIOERR_OUTOFMEMORY; goto OPEN_ERROR; } // Init some member data from format chunk m_nBlockAlign = m_pwfmt->nBlockAlign; m_nAvgDataRate = m_pwfmt->nAvgBytesPerSec; // Ascend out of format chunk if (m_mmr = mmioAscend (m_hmmio, &m_mmckiFmt, 0)) { goto OPEN_ERROR; } // Cue for streaming Cue (); // Init some member data from data chunk // Note cast to __int64 to prevent rollover error in calculation m_nDataSize = m_mmckiData.cksize; m_nDuration = (UINT)(((__int64) m_nDataSize * 1000) / m_nAvgDataRate); // Successful open! goto OPEN_DONE; OPEN_ERROR: // Handle all errors here fRtn = FALSE; if (m_hmmio) { // Close file mmioClose (m_hmmio, 0); m_hmmio = NULL; } if (m_pwfmt) { // UNDONE: Change here if using malloc // Free memory GlobalFree (m_pwfmt); m_pwfmt = NULL; } OPEN_DONE: return (fRtn); }
// Open bool WaveFile::Open(char *pszFilename, bool keep_ext) { int rc = -1; WORD cbExtra = 0; bool fRtn = true; // assume success PCMWAVEFORMAT pcmwf; int FileSize, FileOffset; char fullpath[MAX_PATH]; char filename[MAX_FILENAME_LEN]; const int NUM_EXT = 2; const char *audio_ext[NUM_EXT] = { ".ogg", ".wav" }; m_total_uncompressed_bytes_read = 0; m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX; // NOTE: we assume that the extension has already been stripped off if it was supposed to be!! strcpy_s( filename, pszFilename ); // if we are supposed to load the file as passed... if (keep_ext) { for (int i = 0; i < NUM_EXT; i++) { if ( stristr(pszFilename, audio_ext[i]) ) { rc = i; break; } } // not a supported extension format ... somebody screwed up their tbls :) if (rc < 0) goto OPEN_ERROR; cf_find_file_location(pszFilename, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset); } // ... otherwise we just find the best match else { rc = cf_find_file_location_ext(filename, NUM_EXT, audio_ext, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset); } if (rc < 0) { goto OPEN_ERROR; } else { // set proper filename for later use (assumes that it doesn't already have an extension) strcat_s( filename, audio_ext[rc] ); } m_snd_info.cfp = mmioOpen( fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ ); if (m_snd_info.cfp == NULL) goto OPEN_ERROR; m_snd_info.true_offset = FileOffset; m_snd_info.size = FileSize; // if in a VP then position the stream at the start of the file if (FileOffset > 0) mmioSeek( m_snd_info.cfp, FileOffset, SEEK_SET ); // if Ogg Vorbis... if (rc == 0) { if ( ov_open_callbacks(&m_snd_info, &m_snd_info.vorbis_file, NULL, 0, mmio_callbacks) == 0 ) { // got an Ogg Vorbis, so lets read the info in ov_info(&m_snd_info.vorbis_file, -1); // we only support one logical bitstream if ( ov_streams(&m_snd_info.vorbis_file) != 1 ) { mprintf(("AUDIOSTR => OGG reading error: We don't handle bitstream changes!\n")); goto OPEN_ERROR; } m_wave_format = OGG_FORMAT_VORBIS; m_wfmt.wFormatTag = WAVE_FORMAT_PCM; m_wfmt.nChannels = (WORD) m_snd_info.vorbis_file.vi->channels; m_wfmt.nSamplesPerSec = m_snd_info.vorbis_file.vi->rate; switch (Ds_sound_quality) { case DS_SQ_HIGH: m_wfmt.wBitsPerSample = Ds_float_supported ? 32 : 16; break; case DS_SQ_MEDIUM: m_wfmt.wBitsPerSample = 16; break; default: m_wfmt.wBitsPerSample = 8; break; } m_wfmt.cbSize = 0; m_wfmt.nBlockAlign = (ushort)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8); m_wfmt.nAvgBytesPerSec = m_wfmt.nSamplesPerSec * m_wfmt.nBlockAlign; m_nBlockAlign = m_wfmt.nBlockAlign; m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec; // location of start of file in VP m_data_offset = 0; m_nDataSize = m_data_bytes_left = ((int)ov_pcm_total(&m_snd_info.vorbis_file, -1) * m_wfmt.nBlockAlign); } else { mprintf(("AUDIOSTR => OGG reading error: Not a valid Vorbis file!\n")); } } // if Wave... else if (rc == 1) { bool done = false; // Skip the "RIFF" tag and file size (8 bytes) // Skip the "WAVE" tag (4 bytes) mmioSeek( m_snd_info.cfp, 12+FileOffset, SEEK_SET ); // Now read RIFF tags until the end of file uint tag, size, next_chunk; while ( !done ) { if ( !audiostr_read_uint(m_snd_info.cfp, &tag) ) break; if ( !audiostr_read_uint(m_snd_info.cfp, &size) ) break; next_chunk = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR ); next_chunk += size; switch (tag) { case 0x20746d66: // The 'fmt ' tag { audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.wFormatTag); audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.nChannels); audiostr_read_dword(m_snd_info.cfp, &pcmwf.wf.nSamplesPerSec); audiostr_read_dword(m_snd_info.cfp, &pcmwf.wf.nAvgBytesPerSec); audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.nBlockAlign); audiostr_read_word(m_snd_info.cfp, &pcmwf.wBitsPerSample); if (pcmwf.wf.wFormatTag == WAVE_FORMAT_ADPCM) audiostr_read_word(m_snd_info.cfp, &cbExtra); // Allocate memory for WAVEFORMATEX structure + extra bytes if ( (m_pwfmt_original = (WAVEFORMATEX *) vm_malloc(sizeof(WAVEFORMATEX)+cbExtra)) != NULL ) { Assert(m_pwfmt_original != NULL); // Copy bytes from temporary format structure memcpy (m_pwfmt_original, &pcmwf, sizeof(pcmwf)); m_pwfmt_original->cbSize = cbExtra; // Read those extra bytes, append to WAVEFORMATEX structure if (cbExtra != 0) mmioRead( m_snd_info.cfp, ((char *)(m_pwfmt_original) + sizeof(WAVEFORMATEX)), cbExtra ); } else { Int3(); // malloc failed goto OPEN_ERROR; } break; } case 0x61746164: // the 'data' tag { m_nDataSize = size; // This is size of data chunk. Compressed if ADPCM. m_data_bytes_left = size; m_data_offset = mmioSeek( m_snd_info.cfp, 0, SEEK_CUR ); done = true; break; } default: // unknown, skip it break; } // end switch mmioSeek( m_snd_info.cfp, next_chunk, SEEK_SET ); } // make sure that we did good if ( !done || (m_pwfmt_original == NULL) ) goto OPEN_ERROR; // At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound. // Since DirectSound only supports PCM, force this structure to be PCM compliant. We will // need to convert data on the fly later if our souce is not PCM switch (m_pwfmt_original->wFormatTag) { case WAVE_FORMAT_PCM: m_wave_format = WAVE_FORMAT_PCM; m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample; break; case WAVE_FORMAT_ADPCM: m_wave_format = WAVE_FORMAT_ADPCM; m_wfmt.wBitsPerSample = (Ds_sound_quality) ? 16: 8; m_bits_per_sample_uncompressed = m_wfmt.wBitsPerSample; break; case WAVE_FORMAT_IEEE_FLOAT: { m_wave_format = WAVE_FORMAT_IEEE_FLOAT; switch (Ds_sound_quality) { case DS_SQ_HIGH: m_wfmt.wBitsPerSample = (Ds_float_supported) ? 32 : 16; break; case DS_SQ_MEDIUM: m_wfmt.wBitsPerSample = 16; break; default: m_wfmt.wBitsPerSample = 8; break; } break; } default: nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n", m_pwfmt_original->wFormatTag)); goto OPEN_ERROR; break; } // end switch // Set up the WAVEFORMATEX structure to have the right PCM characteristics m_wfmt.wFormatTag = WAVE_FORMAT_PCM; m_wfmt.nChannels = m_pwfmt_original->nChannels; m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec; m_wfmt.cbSize = 0; m_wfmt.nBlockAlign = (ushort)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8); m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec; // Init some member data from format chunk m_nBlockAlign = m_pwfmt_original->nBlockAlign; m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec; Assert( (m_wfmt.nChannels == 1) || (m_wfmt.nChannels == 2) ); } // something unkown??? else { Int3(); } m_al_format = openal_get_format(m_wfmt.wBitsPerSample, m_wfmt.nChannels); if (m_al_format != AL_INVALID_VALUE) { // Cue for streaming Cue(); goto OPEN_DONE; } OPEN_ERROR: // Handle all errors here nprintf(("SOUND","SOUND ==> Could not open wave file %s for streaming\n", filename)); fRtn = false; if (m_snd_info.cfp != NULL) { // Close file mmioClose( m_snd_info.cfp, 0 ); m_snd_info.cfp = NULL; m_snd_info.true_offset = 0; m_snd_info.size = 0; } if (m_pwfmt_original) { vm_free(m_pwfmt_original); m_pwfmt_original = NULL; } OPEN_DONE: strncpy(m_wFilename, filename, MAX_FILENAME_LEN-1); if (fRtn) nprintf(("SOUND", "AUDIOSTR => Successfully opened: %s\n", filename)); return (fRtn); }
// Open BOOL WaveFile::Open(LPSTR pszFilename) { int done = FALSE, rc = 0; WORD cbExtra = 0; BOOL fRtn = SUCCESS; // assume success PCMWAVEFORMAT pcmwf; char fullpath[_MAX_PATH]; m_total_uncompressed_bytes_read = 0; m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX; int FileSize, FileOffset; if (!cf_find_file_location(pszFilename, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset)) { goto OPEN_ERROR; } m_snd_info.cfp = mmioOpen(fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ); if (m_snd_info.cfp == NULL) { goto OPEN_ERROR; } m_snd_info.true_offset = FileOffset; m_snd_info.size = FileSize; // if in a VP then position the stream at the start of the file if (FileOffset > 0) { mmioSeek(m_snd_info.cfp, FileOffset, SEEK_SET); } // first check for an OGG if ((rc = ov_open_callbacks(&m_snd_info, &m_snd_info.vorbis_file, NULL, 0, mmio_callbacks)) == 0) { // got an OGG so lets read the info in ov_info(&m_snd_info.vorbis_file, -1); // we only support one logical bitstream if (ov_streams(&m_snd_info.vorbis_file) != 1) { mprintf(("AUDIOSTR => OGG reading error: We don't handle bitstream changes!\n")); goto OPEN_ERROR; } m_wave_format = OGG_FORMAT_VORBIS; m_wfmt.wFormatTag = WAVE_FORMAT_PCM; m_wfmt.nChannels = (WORD)m_snd_info.vorbis_file.vi->channels; m_wfmt.nSamplesPerSec = m_snd_info.vorbis_file.vi->rate; m_wfmt.cbSize = 0; if (UserSampleBits == 16 || UserSampleBits == 8) m_wfmt.wBitsPerSample = UserSampleBits; //Decode at whatever the user specifies; only 16 and 8 are supported. else if (UserSampleBits > 16) m_wfmt.wBitsPerSample = 16; else m_wfmt.wBitsPerSample = 8; m_wfmt.nBlockAlign = (ushort)((m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8); m_wfmt.nAvgBytesPerSec = m_wfmt.nSamplesPerSec * m_wfmt.nBlockAlign; m_nBlockAlign = m_wfmt.nBlockAlign; m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec; // location of start of file in VP m_data_offset = 0; m_nDataSize = m_data_bytes_left = ((int)ov_pcm_total(&m_snd_info.vorbis_file, -1) * m_wfmt.nBlockAlign); // Cue for streaming Cue(); // successful open goto OPEN_DONE; } // not an OGG so assume that it's WAVE else { // extra check, if it's not ogg then but if the error was a bad ogg then bail if (rc && (rc != OV_ENOTVORBIS)) goto OPEN_ERROR; // Skip the "RIFF" tag and file size (8 bytes) // Skip the "WAVE" tag (4 bytes) mmioSeek(m_snd_info.cfp, 12 + FileOffset, SEEK_SET); /*char buf[4]; mmioRead(m_snd_info.cfp, buf, sizeof(char)*4); if(strnicmp("RIFF", buf, 4)) goto OPEN_ERROR; //Skip file length mmioSeek( m_snd_info.cfp, 4, SEEK_CUR); mmioRead(m_snd_info.cfp, buf, sizeof(char)*4); if(strnicmp("WAVE", buf, 4)) goto OPEN_ERROR;*/ // Now read RIFF tags until the end of file uint tag, size, next_chunk; while (done == FALSE) { if (mmioRead(m_snd_info.cfp, (char*)&tag, sizeof(uint)) != sizeof(uint)) break; if (mmioRead(m_snd_info.cfp, (char*)&size, sizeof(uint)) != sizeof(uint)) break; next_chunk = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR); next_chunk += size; switch (tag) { case 0x20746d66: // The 'fmt ' tag mmioRead(m_snd_info.cfp, (char*)&pcmwf, sizeof(PCMWAVEFORMAT)); if (pcmwf.wf.wFormatTag != WAVE_FORMAT_PCM) { mmioRead(m_snd_info.cfp, (char*)&cbExtra, sizeof(short)); } // Allocate memory for WAVEFORMATEX structure + extra bytes if ((m_pwfmt_original = (WAVEFORMATEX*)vm_malloc(sizeof(WAVEFORMATEX) + cbExtra)) != NULL) { Assert(m_pwfmt_original != NULL); // Copy bytes from temporary format structure memcpy(m_pwfmt_original, &pcmwf, sizeof(pcmwf)); m_pwfmt_original->cbSize = cbExtra; // Read those extra bytes, append to WAVEFORMATEX structure if (cbExtra != 0) { mmioRead(m_snd_info.cfp, (char*)((ubyte*)(m_pwfmt_original)+ sizeof(WAVEFORMATEX)), cbExtra); } } else { Int3(); // malloc failed goto OPEN_ERROR; } break; case 0x61746164: // the 'data' tag m_nDataSize = size; // This is size of data chunk. Compressed if ADPCM. m_data_bytes_left = size; m_data_offset = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR); done = TRUE; break; default: // unknown, skip it break; } // end switch mmioSeek(m_snd_info.cfp, next_chunk, SEEK_SET); } // At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound. // Since DirectSound only supports PCM, force this structure to be PCM compliant. We will // need to convert data on the fly later if our souce is not PCM switch (m_pwfmt_original->wFormatTag) { case WAVE_FORMAT_PCM: m_wave_format = WAVE_FORMAT_PCM; m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample; break; case WAVE_FORMAT_ADPCM: m_wave_format = WAVE_FORMAT_ADPCM; if (UserSampleBits == 16 || UserSampleBits == 8) m_wfmt.wBitsPerSample = UserSampleBits; //Decode at whatever the user specified, if it's 16 or 8 else if (UserSampleBits > 16) m_wfmt.wBitsPerSample = 16; else m_wfmt.wBitsPerSample = 8; break; default: nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n", m_pwfmt_original->wFormatTag)); //Int3(); goto OPEN_ERROR; break; } // end switch // Set up the WAVEFORMATEX structure to have the right PCM characteristics m_wfmt.wFormatTag = WAVE_FORMAT_PCM; m_wfmt.nChannels = m_pwfmt_original->nChannels; m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec; m_wfmt.cbSize = 0; m_wfmt.nBlockAlign = (unsigned short)((m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8); m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec; // Init some member data from format chunk m_nBlockAlign = m_pwfmt_original->nBlockAlign; m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec; // Cue for streaming Cue(); // Successful open goto OPEN_DONE; } OPEN_ERROR: // Handle all errors here nprintf(("SOUND", "SOUND ==> Could not open wave file %s for streaming\n", pszFilename)); fRtn = FAILURE; if (m_snd_info.cfp != NULL) { // Close file mmioClose(m_snd_info.cfp, 0); m_snd_info.cfp = NULL; m_snd_info.true_offset = 0; m_snd_info.size = 0; } if (m_pwfmt_original) { vm_free(m_pwfmt_original); m_pwfmt_original = NULL; } OPEN_DONE: return (fRtn); }
void CueStack_Test::switchCue() { QLCFixtureDef* def = m_doc->fixtureDefCache()->fixtureDef("Futurelight", "DJScan250"); QVERIFY(def != NULL); QLCFixtureMode* mode = def->modes().first(); QVERIFY(mode != NULL); Fixture* fxi = new Fixture(m_doc); fxi->setFixtureDefinition(def, mode); fxi->setName("Test Scanner"); fxi->setAddress(10); fxi->setUniverse(0); m_doc->addFixture(fxi); QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); CueStack cs(m_doc); cs.setFadeInSpeed(100); cs.setFadeOutSpeed(200); cs.setDuration(300); Cue cue; cue.setName("One"); cue.setValue(0, 255); cue.setValue(1, 255); cue.setValue(500, 255); cue.setValue(10, 255); // LTP cue.setValue(11, 255); // LTP cue.setFadeInSpeed(20); cue.setFadeOutSpeed(40); cs.appendCue(cue); cue = Cue(); cue.setName("Two"); cue.setValue(500, 255); cue.setValue(3, 255); cue.setValue(4, 255); cue.setValue(11, 255); // LTP cue.setFadeInSpeed(60); cue.setFadeOutSpeed(80); cs.appendCue(cue); cs.preRun(); // Do nothing with invalid cue indices cs.switchCue(-1, -1, ua); QCOMPARE(cs.m_fader->channels().size(), 0); cs.switchCue(-1, 3, ua); QCOMPARE(cs.m_fader->channels().size(), 0); // Switch to cue one cs.switchCue(3, 0, ua); QCOMPARE(cs.m_fader->channels().size(), 5); FadeChannel fc; fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(20)); fc.setChannel(1); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(1)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(20)); fc.setChannel(10); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(10)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(20)); fc.setChannel(11); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(11)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(20)); fc.setChannel(500); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(500)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(20)); fc.setChannel(3); QCOMPARE(cs.m_fader->channels()[fc].channel(), QLCChannel::invalid()); fc.setChannel(4); QCOMPARE(cs.m_fader->channels()[fc].channel(), QLCChannel::invalid()); fc.setChannel(0); cs.m_fader->m_channels[fc].setCurrent(127); fc.setChannel(1); cs.m_fader->m_channels[fc].setCurrent(127); fc.setChannel(10); cs.m_fader->m_channels[fc].setCurrent(127); fc.setChannel(11); cs.m_fader->m_channels[fc].setCurrent(127); fc.setChannel(500); cs.m_fader->m_channels[fc].setCurrent(127); // Switch to cue two cs.switchCue(0, 1, ua); QCOMPARE(cs.m_fader->channels().size(), 7); fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(40)); fc.setChannel(1); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(1)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(40)); fc.setChannel(11); // LTP channel also in the next cue QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(11)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(60)); fc.setChannel(500); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(127)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(500)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(60)); fc.setChannel(3); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(3)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(60)); fc.setChannel(4); QCOMPARE(cs.m_fader->channels()[fc].start(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].current(), uchar(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(4)); QCOMPARE(cs.m_fader->channels()[fc].fadeTime(), uint(60)); // Stop cs.switchCue(1, -1, ua); QCOMPARE(cs.m_fader->channels().size(), 7); MasterTimer mt(m_doc); cs.postRun(&mt); }
void CueStack_Test::insertCue() { CueStack cs(m_doc); QCOMPARE(cs.cues().size(), 0); QSignalSpy spy(&cs, SIGNAL(currentCueChanged(int))); cs.insertCue(0, Cue("One")); QCOMPARE(cs.cues().size(), 1); QCOMPARE(cs.cues()[0].name(), QString("One")); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(spy.size(), 0); cs.insertCue(0, Cue("Two")); QCOMPARE(cs.cues().size(), 2); QCOMPARE(cs.cues()[0].name(), QString("Two")); QCOMPARE(cs.cues()[1].name(), QString("One")); QCOMPARE(cs.currentIndex(), -1); QCOMPARE(spy.size(), 0); cs.setCurrentIndex(1); cs.insertCue(2, Cue("Three")); QCOMPARE(cs.cues().size(), 3); QCOMPARE(cs.cues()[0].name(), QString("Two")); QCOMPARE(cs.cues()[1].name(), QString("One")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.currentIndex(), 1); QCOMPARE(spy.size(), 0); cs.setCurrentIndex(1); cs.insertCue(20, Cue("Four")); QCOMPARE(cs.cues().size(), 4); QCOMPARE(cs.cues()[0].name(), QString("Two")); QCOMPARE(cs.cues()[1].name(), QString("One")); QCOMPARE(cs.cues()[2].name(), QString("Three")); QCOMPARE(cs.cues()[3].name(), QString("Four")); QCOMPARE(cs.currentIndex(), 1); QCOMPARE(spy.size(), 0); cs.setCurrentIndex(1); cs.insertCue(1, Cue("Five")); QCOMPARE(cs.cues().size(), 5); QCOMPARE(cs.cues()[0].name(), QString("Two")); QCOMPARE(cs.cues()[1].name(), QString("Five")); QCOMPARE(cs.cues()[2].name(), QString("One")); QCOMPARE(cs.cues()[3].name(), QString("Three")); QCOMPARE(cs.cues()[4].name(), QString("Four")); QCOMPARE(cs.currentIndex(), 2); QCOMPARE(spy.size(), 1); QCOMPARE(spy.at(0).at(0).toInt(), 2); cs.insertCue(-1, Cue("Six")); QCOMPARE(cs.cues().size(), 6); QCOMPARE(cs.cues()[0].name(), QString("Two")); QCOMPARE(cs.cues()[1].name(), QString("Five")); QCOMPARE(cs.cues()[2].name(), QString("One")); QCOMPARE(cs.cues()[3].name(), QString("Three")); QCOMPARE(cs.cues()[4].name(), QString("Four")); QCOMPARE(cs.cues()[5].name(), QString("Six")); QCOMPARE(cs.currentIndex(), 2); QCOMPARE(spy.size(), 1); }