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; }
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 */