Ejemplo n.º 1
0
void AudioScheduledSourceHandler::finishWithoutOnEnded() {
  if (playbackState() != FINISHED_STATE) {
    // Let the context dereference this AudioNode.
    context()->notifySourceNodeFinishedProcessing(this);
    setPlaybackState(FINISHED_STATE);
  }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 5
0
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
		}
	}
}