long int lp_libdv_in::read_samples(float *buffer, long int len)
{
	int audio_decoded = 0, file_readen = 0;
	int i, channel;
//	std::cerr << "lp_libdv_in::" << __FUNCTION__ << " called\n";

	// TESTS
	len = len/2;

  /* Interleave the audio into a single buffer */
/*  for (i = 0, samples = dv_get_num_samples (dv), channels = dv_get_num_channels (dv);
       i < samples; i++) {
    for (ch = 0; ch < channels; ch++) {
      oss -> buffer [j++] = out [ch] [i];
    }
  }
*/

	// Check if decoding is requierd
	//while(pv_audio_num_ready <= len){
	while(pv_lp_audio_buffer.left() <= len){
		file_readen = read(pv_fd, pv_file_buffer, 144000); // FIXME: len to read ?
		// decode a video frame and display - NOTE this part must move to another class later...
		dv_decode_full_frame(pv_decoder, pv_file_buffer, pv_color_space, pv_sdl_out->pb_pixels, pv_sdl_out->pb_pitches);
		pv_sdl_out->display();
		// decode audio
		dv_decode_full_audio(pv_decoder, pv_file_buffer, pv_dv_audio_buffers);
		audio_decoded = dv_get_num_samples(pv_decoder);
		// Copy to ready buffer
		
		//for(i=0; i<audio_decoded; i++){
			for(channel = 0; channel < pv_audio_channels; channel++){
				// write to ready buffer from start position
				//pv_audio_ready_buffer[pv_audio_decoder_start+channel+i*pv_audio_channels] = pv_dv_audio_buffers[channel][i];
				pv_lp_audio_buffer.put(pv_dv_audio_buffers[channel], audio_decoded / pv_audio_channels);
			}
		//}
		pv_audio_num_ready = pv_audio_num_ready + audio_decoded;
		// update start pos
		pv_audio_decoder_start = pv_audio_decoder_start + audio_decoded;
	}

	pv_lp_audio_buffer.get(pv_audio_ready_buffer, len);

	float tmp;
	// Copy needed to output buffer
	for(i=0; i<len; i++){
		//buffer[i] = (float)(pv_audio_ready_buffer[pv_audio_decoder_start+i] / 32768);
		//buffer[i] = (float)(pv_audio_ready_buffer[pv_audio_decoder_start+i] / 4000);
		tmp = (float)pv_audio_ready_buffer[i];
		buffer[i] = tmp / 6000.0;
		//buffer[i] = (float)(pv_audio_ready_buffer[i] / 6000);
	}
	// update start pos
	pv_audio_consumer_start = pv_audio_decoder_start + len;

	// Calcule samples consomés
	pv_audio_num_ready = pv_audio_num_ready - len;

	// On déplace le reste au début de pv_audio_ready buffer
/*	if(pv_audio_num_ready > 0){
		for(i=0; i<pv_audio_num_ready; i++){
			pv_audio_ready_buffer[i] = pv_audio_ready_buffer[pv_audio_decoder_start+i];
		}
		// reset positions
		pv_audio_decoder_start = 0;
		pv_audio_consumer_start = 0;
	}
*/
//	std::cout << "Décodés: " << pv_audio_num_ready << " - consommés: " << len << " - prêts: " << pv_audio_num_ready << "\n";
//	std::cout << "Start decodeur: " << pv_audio_decoder_start << " - start consumer: " << pv_audio_consumer_start << "\n\n";

	// THIS is false !
	//return file_readen;
	return len;
}
Exemple #2
0
dv_oss_t *
dv_oss_new(void)
{
  dv_oss_t *result;
  
  result = (dv_oss_t *)calloc(1,sizeof(dv_oss_t));
  if(!result) goto no_mem;

#if HAVE_LIBPOPT
  result->option_table[DV_OSS_OPT_DEVICE] = (struct poptOption) {
    longName:   "audio-device", 
    argInfo:    POPT_ARG_STRING, 
    arg:        &result->arg_audio_device,
    descrip:    "target audio device; e.g. /dev/dsp [default]",
    argDescrip: "devicename",
  }; /* device */

  result->option_table[DV_OSS_OPT_FILE] = (struct poptOption) {
    longName:   "audio-file", 
    argInfo:    POPT_ARG_STRING, 
    arg:        &result->arg_audio_file,
    descrip:    "send raw decoded audio to file, skipping audio ioctls",
    argDescrip: "filename",
  }; /* file */
#endif // HAVE_LIBPOPT

 no_mem:
  return(result);
} /* dv_oss_new */

/* Very simplistic for sound output using the OSS API */
int
dv_oss_init(dv_decoder_t *dv, dv_oss_t *oss)
{
  int   format = AFMT_S16_NE, rate_request, channels_request;
  char  *device;

  channels_request = dv_get_num_channels (dv);
  rate_request = dv_get_frequency (dv);
  oss->buffer=NULL;
  oss->fd=-1;
  if(oss->arg_audio_device && oss->arg_audio_file) goto usage;
  if(oss->arg_audio_file) {
    if ((oss->fd = open(oss->arg_audio_file,
			O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE,
			S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) == -1) goto no_file;
  } else {
    device = (char *)(oss->arg_audio_device ? oss->arg_audio_device : default_device);
    /* open audio device */
    if ((oss->fd = open(device, O_RDWR, 0)) == -1) goto no_device;
    /* set sample format -- try for 16bit */
    if (ioctl(oss->fd, SNDCTL_DSP_SETFMT, &format) == -1) goto format_ioctl;
    if (format != AFMT_S16_NE) goto format_unsupported;
    /* set stereo mode */
    if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &channels_request) == -1) goto channels_ioctl;
    if (channels_request != dv_get_num_channels (dv)) goto channels_unsupported;
    /* set sampling rate */
    if (ioctl(oss->fd, SNDCTL_DSP_SPEED, &rate_request) == -1) goto rate_ioctl;
    if(rate_request != dv_get_frequency (dv)) goto rate_unsupported;
  }
  if(!(oss->buffer = malloc(DV_AUDIO_MAX_SAMPLES * channels_request * sizeof(short)))) goto no_memory;
  return(TRUE);

 usage:
  fprintf(stderr,"can't send audio to both device and file\n");
  exit(-1);

 format_unsupported:
  fprintf(stderr, "soundcard doesn't support format\n");
  goto fail;

 rate_unsupported:
  fprintf(stderr,"audio rate found : %d Hz\n", rate_request);
  fprintf(stderr, "soundcard doesn't support 48kHz (does %d)\n", rate_request);
  goto fail;

 channels_unsupported:
  fprintf(stderr, "soundcard doesn't support %d channels\n", channels_request);
  goto fail;

 no_device:
  perror(device);
  goto fail;

 no_file:
  perror(oss->arg_audio_file);
  goto fail;

 format_ioctl:
  perror("SNDCTL_DSP_SETFMT");
  goto fail;

 channels_ioctl:
  perror("SNDCTL_DSP_CHANNELS");
  goto fail;

 rate_ioctl:
  perror("SNDCTL_DSP_SPEED");
  goto fail;

 no_memory:
  fprintf(stderr, "out of memory\n");
  goto fail;

 fail:
  dv_oss_close(oss);
  return(FALSE);
} /* dv_oss_init */

int
dv_oss_play(dv_decoder_t *dv, dv_oss_t *oss, short **out)
{
  int ch, i, j=0, total, written=0, result, samples, channels;

  /* Interleave the audio into a single buffer */
  for (i = 0, samples = dv_get_num_samples (dv), channels = dv_get_num_channels (dv);
       i < samples; i++) {
    for (ch = 0; ch < channels; ch++) {
      oss -> buffer [j++] = out [ch] [i];
    } /* for */
  } /* for */

  /* Send the audio to the device */
  total = samples * channels * sizeof (short);
  do {
    result = write(oss->fd, oss->buffer + written, total - written);
    if(result <= 0) goto write_error;
    written += result;
  } while(total > written);
  if(!oss->arg_audio_file) {
    if (ioctl(oss->fd, SNDCTL_DSP_POST, NULL) == -1) goto post_ioctl;
  } /* if */

  return(TRUE);

 write_error:
  perror("write");
  return(FALSE);

 post_ioctl:
  perror("SNDCTL_DSP_POST");
  return(FALSE);

} /* dv_oss_play */