void AudioScheduledSourceHandler::finishWithoutOnEnded() { if (playbackState() != FINISHED_STATE) { // Let the context dereference this AudioNode. context()->notifySourceNodeFinishedProcessing(this); setPlaybackState(FINISHED_STATE); } }
void AudioScheduledSourceHandler::stop(double when, ExceptionState& exceptionState) { DCHECK(isMainThread()); if (playbackState() == UNSCHEDULED_STATE) { exceptionState.throwDOMException( InvalidStateError, "cannot call stop without calling start first."); return; } if (when < 0) { exceptionState.throwDOMException( InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("stop time", when, 0.0)); return; } // This synchronizes with process() MutexLocker processLocker(m_processLock); // stop() can be called more than once, with the last call to stop taking // effect, unless the source has already stopped due to earlier calls to stop. // No exceptions are thrown in any case. when = std::max(0.0, when); m_endTime = when; }
void AudioScheduledSourceHandler::start(double when, ExceptionState& exceptionState) { DCHECK(isMainThread()); context()->maybeRecordStartAttempt(); if (playbackState() != UNSCHEDULED_STATE) { exceptionState.throwDOMException(InvalidStateError, "cannot call start more than once."); return; } if (when < 0) { exceptionState.throwDOMException( InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("start time", when, 0.0)); return; } // The node is started. Add a reference to keep us alive so that audio will // eventually get played even if Javascript should drop all references to this // node. The reference will get dropped when the source has finished playing. context()->notifySourceNodeStartedProcessing(node()); // This synchronizes with process(). updateSchedulingInfo will read some of // the variables being set here. MutexLocker processLocker(m_processLock); // If |when| < currentTime, the source must start now according to the spec. // So just set startTime to currentTime in this case to start the source now. m_startTime = std::max(when, context()->currentTime()); setPlaybackState(SCHEDULED_STATE); }
void AudioBufferSourceHandler::startSource(double when, double grainOffset, double grainDuration, bool isDurationGiven, ExceptionState& exceptionState) { ASSERT(isMainThread()); context()->recordUserGestureState(); if (playbackState() != UNSCHEDULED_STATE) { exceptionState.throwDOMException( InvalidStateError, "cannot call start more than once."); return; } if (when < 0) { exceptionState.throwDOMException( InvalidStateError, ExceptionMessages::indexExceedsMinimumBound( "start time", when, 0.0)); return; } if (grainOffset < 0) { exceptionState.throwDOMException( InvalidStateError, ExceptionMessages::indexExceedsMinimumBound( "offset", grainOffset, 0.0)); return; } if (grainDuration < 0) { exceptionState.throwDOMException( InvalidStateError, ExceptionMessages::indexExceedsMinimumBound( "duration", grainDuration, 0.0)); return; } // The node is started. Add a reference to keep us alive so that audio // will eventually get played even if Javascript should drop all references // to this node. The reference will get dropped when the source has finished // playing. context()->notifySourceNodeStartedProcessing(node()); // This synchronizes with process(). updateSchedulingInfo will read some of the variables being // set here. MutexLocker processLocker(m_processLock); m_isDurationGiven = isDurationGiven; m_isGrain = true; m_grainOffset = grainOffset; m_grainDuration = grainDuration; // If |when| < currentTime, the source must start now according to the spec. // So just set startTime to currentTime in this case to start the source now. m_startTime = std::max(when, context()->currentTime()); if (buffer()) clampGrainParameters(buffer()); setPlaybackState(SCHEDULED_STATE); }
void AudioScheduledSourceHandler::updateSchedulingInfo( size_t quantumFrameSize, AudioBus* outputBus, size_t& quantumFrameOffset, size_t& nonSilentFramesToProcess) { DCHECK(outputBus); if (!outputBus) return; DCHECK_EQ(quantumFrameSize, static_cast<size_t>(AudioUtilities::kRenderQuantumFrames)); if (quantumFrameSize != AudioUtilities::kRenderQuantumFrames) return; double sampleRate = this->sampleRate(); // quantumStartFrame : Start frame of the current time quantum. // quantumEndFrame : End frame of the current time quantum. // startFrame : Start frame for this source. // endFrame : End frame for this source. size_t quantumStartFrame = context()->currentSampleFrame(); size_t quantumEndFrame = quantumStartFrame + quantumFrameSize; size_t startFrame = AudioUtilities::timeToSampleFrame(m_startTime, sampleRate); size_t endFrame = m_endTime == UnknownTime ? 0 : AudioUtilities::timeToSampleFrame( m_endTime, sampleRate); // If we know the end time and it's already passed, then don't bother doing // any more rendering this cycle. if (m_endTime != UnknownTime && endFrame <= quantumStartFrame) finish(); PlaybackState state = playbackState(); if (state == UNSCHEDULED_STATE || state == FINISHED_STATE || startFrame >= quantumEndFrame) { // Output silence. outputBus->zero(); nonSilentFramesToProcess = 0; return; } // Check if it's time to start playing. if (state == SCHEDULED_STATE) { // Increment the active source count only if we're transitioning from // SCHEDULED_STATE to PLAYING_STATE. setPlaybackState(PLAYING_STATE); } quantumFrameOffset = startFrame > quantumStartFrame ? startFrame - quantumStartFrame : 0; quantumFrameOffset = std::min(quantumFrameOffset, quantumFrameSize); // clamp to valid range nonSilentFramesToProcess = quantumFrameSize - quantumFrameOffset; if (!nonSilentFramesToProcess) { // Output silence. outputBus->zero(); return; } // Handle silence before we start playing. // Zero any initial frames representing silence leading up to a rendering // start time in the middle of the quantum. if (quantumFrameOffset) { for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) memset(outputBus->channel(i)->mutableData(), 0, sizeof(float) * quantumFrameOffset); } // Handle silence after we're done playing. // If the end time is somewhere in the middle of this time quantum, then zero // out the frames from the end time to the very end of the quantum. if (m_endTime != UnknownTime && endFrame >= quantumStartFrame && endFrame < quantumEndFrame) { size_t zeroStartFrame = endFrame - quantumStartFrame; size_t framesToZero = quantumFrameSize - zeroStartFrame; bool isSafe = zeroStartFrame < quantumFrameSize && framesToZero <= quantumFrameSize && zeroStartFrame + framesToZero <= quantumFrameSize; DCHECK(isSafe); if (isSafe) { if (framesToZero > nonSilentFramesToProcess) nonSilentFramesToProcess = 0; else nonSilentFramesToProcess -= framesToZero; for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) memset(outputBus->channel(i)->mutableData() + zeroStartFrame, 0, sizeof(float) * framesToZero); } finish(); } return; }
int main(void) //main program { ex_sask_init( ); //init sask ADCChannelInit (pADCChannelHandle,adcBuffer); //init audio input handler OCPWMInit (pOCPWMHandle,ocPWMBuffer); ADCChannelStart (pADCChannelHandle); //start audio input handler OCPWMStart (pOCPWMHandle); while(1) { if(state==0) //Program is in READY state { state=0; //set state to 0[READY] state=displayState(STATE_READY); //call ready state function and read new state back turnOffAll(); //turn off all LEDs when leaving ready state } else if(state==1) //Program is in READ state { while(ADCChannelIsBusy(pADCChannelHandle)); //read audio input ADCChannelRead (pADCChannelHandle,AudioIn,FFT_FRAME_SIZE); state=3; } else if(state==3) //Program is in ANALZYE state { int i=0; analysingState(1); FFT(&AudioIn, &FFTcompResults); //FFT function used on audio input, using FFT_FRAME_SIZE and returning the results in FFTcompResults analysingState(2); generateAuralisation(&AuralisationWorkSpace, &FFTcompResults); analysingState(3); for(i=0;i<FFT_FRAME_SIZE;i++) { inverseFFT(AudioOut[i], AuralisationWorkSpace[i]); } state=displayState(STATE_ANALYSE); //analising finished } else if(state==4) //Program is in PLAY BACK state { int x; for(x=0;x<FFT_FRAME_SIZE;x++) { while(OCPWMIsBusy(pOCPWMHandle)); OCPWMWrite (pOCPWMHandle,AudioOut[x],FFT_FRAME_SIZE); playbackState(); } OCPWMStop (pOCPWMHandle); //stop audio output state=0; } else //Program is in ERROR state { state=displayState(STATE_ERROR); //show error state on LEDs and read new state } } }