Exemple #1
0
static int sleep_until_start_request_or_inactivity()
{
  SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > ENTER");
  int a_start_is_required=0;

  // Wait for the start request (my_sem_start_is_required).
  // Besides this, if the audio stream is still busy, 
  // check from time to time its end. 
  // The end of the stream is confirmed by several checks 
  // for filtering underflow.
  //
  int i=0;
	while((i<= MAX_INACTIVITY_CHECK) && !a_start_is_required)
	{
		if (wave_is_busy( NULL) )
		{
			i = 0;
		}
      else
		{
			i++;
		}

		int err=0;
		struct timespec ts;
		struct timeval tv;

		clock_gettime2( &ts);

#ifdef DEBUG_ENABLED
		struct timespec to;
		to.tv_sec = ts.tv_sec;
		to.tv_nsec = ts.tv_nsec;
#endif

		add_time_in_ms( &ts, INACTIVITY_TIMEOUT);

		SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n", 
			to.tv_sec, to.tv_nsec,
			ts.tv_sec, ts.tv_nsec);

		while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1 
			&& errno == EINTR)
		{
			continue;
		}

		assert (gettimeofday(&tv, NULL) != -1);
		SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err, 
			tv.tv_sec, tv.tv_usec*1000);

		if (err==0)
		{
			a_start_is_required = 1;
		}
	}
	SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > LEAVE");
	return a_start_is_required;
}
Exemple #2
0
ESPEAK_API int espeak_IsPlaying(void)
{//==================================
//	ENTER("espeak_IsPlaying");
#ifdef USE_ASYNC
	if((my_mode == AUDIO_OUTPUT_PLAYBACK) && wave_is_busy(my_audio))
		return(1);

	return(fifo_is_busy());
#else
	return(0);
#endif
}   //  end of espeak_IsPlaying
Exemple #3
0
static int get_remaining_time(uint32_t sample, uint32_t* time_in_ms, int* stop_is_required)
{
ENTER("get_remaining_time");

	int err = 0;
	*stop_is_required = 0;
	int i=0;

	for (i=0; i < MAX_ACTIVITY_CHECK && (*stop_is_required == 0); i++)
	{
		err = wave_get_remaining_time( sample, time_in_ms);

		if (err || wave_is_busy(NULL) || (*time_in_ms == 0))
		{ // if err, stream not available: quit
	  // if wave is busy, time_in_ms is known: quit
	  // if wave is not busy but remaining time == 0, event is reached: quit
		break;
	}

      // stream opened but not active
      //
      // Several possible states: 
      //   * the stream is opened but not yet started: 
      //
      //       wait for the start of stream
      //
      //   * some samples have already been played, 
      //      ** the end of stream is reached
      //      ** or there is an underrun
      //      
      //       wait for the close of stream

		*stop_is_required = sleep_until_timeout_or_stop_request( ACTIVITY_TIMEOUT);      
	}

	return err;
}
Exemple #4
0
size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize)
{
	ENTER("wave_write");
	size_t bytes_written = 0;
	// space in ringbuffer for the sample needed: 1x mono channel but 2x for 1 stereo channel
	size_t bytes_to_write = (out_channels==1) ? theSize : theSize*2;
	my_stream_could_start = 0;
 
	if(pa_stream == NULL)
	{
		SHOW_TIME("wave_write > wave_open_sound\n");
		if (0 != wave_open_sound())
		{
			SHOW_TIME("wave_write > wave_open_sound fails!");
			return 0;
		}
		my_stream_could_start=1;
	}
	else if (!wave_is_busy(NULL))
	{
		my_stream_could_start = 1;
	}
	assert(BUFFER_LENGTH >= bytes_to_write);
 
	if (myWrite >= myBuffer + BUFFER_LENGTH)
	{
		myWrite = myBuffer;
	} // end if (myWrite >= myBuffer + BUFFER_LENGTH)
 
	size_t aTotalFreeMem=0;
	char* aRead = myRead;
	SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite);
 
	while (1)
	{
		if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled()))
		{
			SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
			return 0;
		}
 
		aRead = myRead;
 
		// write pointer is before read pointer?
		if (myWrite >= aRead)
		{
			aTotalFreeMem = aRead + BUFFER_LENGTH - myWrite;
		}
		else // read pointer is before write pointer!
		{
			aTotalFreeMem = aRead - myWrite;
		} // end if (myWrite >= aRead)
 
		if (aTotalFreeMem>1)
		{
			// -1 because myWrite must be different of aRead
			// otherwise buffer would be considered as empty
			aTotalFreeMem -= 1;
		} // end if (aTotalFreeMem>1)
 
		if (aTotalFreeMem >= bytes_to_write)
		{
			break;
		} // end if (aTotalFreeMem >= bytes_to_write)
		
		//SHOW_TIME("wave_write > wait");
		SHOW("wave_write > wait: aTotalFreeMem=%d\n", aTotalFreeMem);
		SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite);
		usleep(10000);
	} // end while (1)
 
	aRead = myRead;
 
	// write pointer is ahead the read pointer?
	if (myWrite >= aRead)
	{
		SHOW_TIME("wave_write > myWrite >= aRead");
		// determine remaining free memory to the end of the ringbuffer
		size_t aFreeMem = myBuffer + BUFFER_LENGTH - myWrite;
		// is enough linear space available (regardless 1 or 2 channels)?
		if (aFreeMem >= bytes_to_write)
		{
			// copy direct - no wrap around at end of ringbuffer needed
			myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);
		}
		else // not enough linear space available
		{
			// 2 channels (stereo)?
			if (out_channels == 2)
			{
				// copy with wrap around at the end of ringbuffer
				copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem/2);
				myWrite = myBuffer;
				myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem/2, theSize - aFreeMem/2);
			}
			else // 1 channel (mono)
			{
				// copy with wrap around at the end of ringbuffer
				copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem);
				myWrite = myBuffer;
				myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem, theSize - aFreeMem);
			} // end if (out_channels == 2)
		} // end if (aFreeMem >= bytes_to_write)
	} // if (myWrite >= aRead)
	else // read pointer is ahead the write pointer
	{
		SHOW_TIME("wave_write > myWrite <= aRead");
		myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);
	} // end if (myWrite >= aRead)
 
	bytes_written = bytes_to_write;
	myWritePosition += theSize/sizeof(uint16_t); // add number of samples
 
	if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER))
	{
		start_stream();
	} // end if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER))
 
	SHOW_TIME("wave_write > LEAVE");
 
	return bytes_written;
}