void EngineRecord::writeCueLine() { if (!m_pCurrentTrack) { return; } // CDDA is specified as having 75 frames a second unsigned long cueFrame = ((unsigned long) ((m_frames / (m_sampleRate / 75))) % 75); m_cueFile.write(QString(" TRACK %1 AUDIO\n") .arg((double)m_cueTrack, 2, 'f', 0, '0') .toLatin1()); m_cueFile.write(QString(" TITLE \"%1\"\n") .arg(m_pCurrentTrack->getTitle()).toLatin1()); m_cueFile.write(QString(" PERFORMER \"%1\"\n") .arg(m_pCurrentTrack->getArtist()).toLatin1()); // Woefully inaccurate (at the seconds level anyways). // We'd need a signal fired state tracker // for the track detection code. m_cueFile.write(QString(" INDEX 01 %1:%2\n") .arg(getRecordedDurationStr()) .arg((double)cueFrame, 2, 'f', 0, '0').toLatin1()); }
void EngineRecord::process(const CSAMPLE* pBuffer, const int iBufferSize) { float recordingStatus = m_pRecReady->get(); if (recordingStatus == RECORD_OFF) { //qDebug("Setting record flag to: OFF"); if (fileOpen()) { Event::end("EngineRecord recording"); closeFile(); // Close file and free encoder. emit(isRecording(false)); } } else if (recordingStatus == RECORD_READY) { // If we are ready for recording, i.e, the output file has been selected, we // open a new file. updateFromPreferences(); // Update file location from preferences. if (openFile()) { Event::start("EngineRecord recording"); qDebug("Setting record flag to: ON"); m_pRecReady->set(RECORD_ON); emit(isRecording(true)); // will notify the RecordingManager // Since we just started recording, timeout and clear the metadata. m_iMetaDataLife = kMetaDataLifeTimeout; m_pCurrentTrack = TrackPointer(); // clean frames couting and get current sample rate. m_frames = 0; m_sampleRate = m_pSamplerate->get(); if (m_bCueIsEnabled) { openCueFile(); m_cueTrack = 0; } } else { // Maybe the encoder could not be initialized qDebug("Setting record flag to: OFF"); m_pRecReady->slotSet(RECORD_OFF); emit(isRecording(false)); } } else if (recordingStatus == RECORD_ON) { // If recording is enabled process audio to compressed or uncompressed data. if (m_encoding == ENCODING_WAVE || m_encoding == ENCODING_AIFF) { if (m_pSndfile != NULL) { sf_write_float(m_pSndfile, pBuffer, iBufferSize); emit(bytesRecorded(iBufferSize * 2)); } } else { if (m_pEncoder) { // Compress audio. Encoder will call method 'write()' below to // write a file stream m_pEncoder->encodeBuffer(pBuffer, iBufferSize); } } // update frames counting and recorded duration (seconds) m_frames += iBufferSize / 2; unsigned long lastDuration = m_recordedDuration; m_recordedDuration = m_frames / m_sampleRate; // gets recorded duration and emit signal that will be used // by RecordingManager to update the label besides start/stop button if (lastDuration != m_recordedDuration) { emit(durationRecorded(getRecordedDurationStr())); } if (m_bCueIsEnabled) { if (metaDataHasChanged()) { m_cueTrack++; writeCueLine(); m_cueFile.flush(); } } } }