static void play_callback(snd_async_handler_t *ahandler) { snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); int err; signed short *samples_buf; samples_buf = malloc((period_size * channels * snd_pcm_format_physical_width(format)) / 8); if(file_capture == 0) { printf("err file\r\n"); } struct timeval oldtv; struct timeval tv; /*avasounil = snd_pcm_avail_update(handle);*/ if ((err = snd_pcm_readi (handle, samples_buf,period_size)) != period_size) { fprintf (stderr, "read from audio interface failed (%s)\n",snd_strerror (err)); exit (1); } else { gettimeofday(&tv,NULL); printf("time %lu\n",(tv.tv_sec-oldtv.tv_sec)*1000000+tv.tv_usec-oldtv.tv_usec); oldtv = tv; fwrite(samples_buf,2,910,file_capture); } }
// Preps and invokes the _InternalCallback above. This provides a cdecl-compliant // entry point for our C++ified object state. :) static void ExternalCallback(snd_async_handler_t *pcm_call) { fprintf(stderr, "* SPU2-X:Iz in your external callback.\n"); AlsaMod *data = (AlsaMod *)snd_async_handler_get_callback_private(pcm_call); pxAssume(data != NULL); //pxAssume( data->handle == snd_async_handler_get_pcm(pcm_call) ); // Not sure if we just need an assert, or something like this: if (data->handle != snd_async_handler_get_pcm(pcm_call)) { fprintf(stderr, "* SPU2-X: Failed to handle sound.\n"); return; } data->_InternalCallback(); }
static void play_callback(snd_async_handler_t *ahandler) { snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); int err; signed short *samples_buf; //samples_buf = malloc((period_size * channels * snd_pcm_format_physical_width(format)) / 8); //if(file_capture == 0) //{ // printf("err file\r\n"); //} static int flag = 0; static struct timeval oldtv; static struct timeval tv; /*avasounil = snd_pcm_avail_update(handle);*/ if(flag == 0) { gettimeofday(&tv,NULL); printf("play back time diff %lu\n",(tv.tv_sec-oldtv.tv_sec)*1000000+tv.tv_usec-oldtv.tv_usec); printf("play time %u: %u \n",tv.tv_sec,tv.tv_usec); oldtv = tv; flag = 1; } }
static void async_callback(snd_async_handler_t *ahandler) { snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); struct async_private_data *data = snd_async_handler_get_callback_private(ahandler); signed short *samples = data->samples; snd_pcm_channel_area_t *areas = data->areas; snd_pcm_sframes_t avail; int err; avail = snd_pcm_avail_update(handle); while (avail >= period_size) { generate_sine(areas, 0, period_size, &data->phase); err = snd_pcm_writei(handle, samples, period_size); if (err < 0) { printf("Initial write error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } if (err != period_size) { printf("Initial write error: written %i expected %li\n", err, period_size); exit(EXIT_FAILURE); } avail = snd_pcm_avail_update(handle); } }
void AudioDriver_ALSA::async_direct_callback(snd_async_handler_t *ahandler) { snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); AudioDriver_ALSA* audioDriver = (AudioDriver_ALSA*) snd_async_handler_get_callback_private(ahandler); const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t offset, frames, size; snd_pcm_sframes_t avail, commitres; snd_pcm_state_t state; int first = 0, err; while (1) { state = snd_pcm_state(handle); if (state == SND_PCM_STATE_XRUN) { err = snd_pcm_recover(handle, -EPIPE, 0); if (err < 0) { fprintf(stderr, "ALSA: XRUN recovery failed: %s\n", snd_strerror(err)); } first = 1; } else if (state == SND_PCM_STATE_SUSPENDED) { err = snd_pcm_recover(handle, ESTRPIPE, 0); if (err < 0) { fprintf(stderr, "ALSA: SUSPEND recovery failed: %s\n", snd_strerror(err)); } } avail = snd_pcm_avail_update(handle); if (avail < 0) { err = snd_pcm_recover(handle, avail, 0); if (err < 0) { fprintf(stderr, "ALSA: avail update failed: %s\n", snd_strerror(err)); } first = 1; continue; } if (avail < audioDriver->period_size) { if (first) { first = 0; err = snd_pcm_start(handle); if (err < 0) { fprintf(stderr, "ALSA: Start error: %s\n", snd_strerror(err)); } } else { break; } continue; } frames = audioDriver->period_size; err = snd_pcm_mmap_begin(handle, &my_areas, &offset, &frames); if (err < 0) { if ((err = snd_pcm_recover(handle, err, 0)) < 0) { fprintf(stderr, "ALSA: MMAP begin avail error: %s\n", snd_strerror(err)); } first = 1; } if(frames != audioDriver->period_size) fprintf(stderr, "ALSA: Invalid buffer size: %lu (should be %lu), skipping..\n", frames, audioDriver->period_size); // Certain audio drivers will periodically request buffers of less than one period when // soft-resampling (ie, not running at native frequency). Milkytracker can't handle this, // and bad things happen - so best to warn the user and not process. // PS - I've disabled soft-resampling for now (see below) so this shouldn't happen. // PPS - The downside is that if the user has the wrong mixer rate, they will get an error // dialog - hopefully they'll read the message on stderr... else audioDriver->fillAudioWithCompensation(static_cast<char*> (my_areas->addr) + offset*4, frames * 2); commitres = snd_pcm_mmap_commit(handle, offset, frames); if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) { if ((err = snd_pcm_recover(handle, commitres >= 0 ? -EPIPE : commitres, 0)) < 0) { fprintf(stderr, "ALSA: MMAP commit error: %s\n", snd_strerror(err)); // What now? // exit(1); } first = 1; } } }
static void async_direct_callback(snd_async_handler_t *ahandler) { snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); struct sniffer_state *sns = snd_async_handler_get_callback_private(ahandler); const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t offset, frames, size; snd_pcm_sframes_t avail, commitres; snd_pcm_state_t state; int first = 0, err; while (1) { state = snd_pcm_state(handle); if (state == SND_PCM_STATE_XRUN) { err = xrun_recovery(handle, -EPIPE); if (err < 0) { printf("XRUN recovery failed: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } first = 1; } else if (state == SND_PCM_STATE_SUSPENDED) { err = xrun_recovery(handle, -ESTRPIPE); if (err < 0) { printf("SUSPEND recovery failed: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } } avail = snd_pcm_avail_update(handle); if (avail < 0) { err = xrun_recovery(handle, avail); if (err < 0) { printf("avail update failed: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } first = 1; continue; } if (avail < sns->period_size) { if (first) { first = 0; err = snd_pcm_start(handle); if (err < 0) { printf("Start error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } } else { break; } continue; } size = sns->period_size; while (size > 0) { frames = size; err = snd_pcm_mmap_begin(handle, &my_areas, &offset, &frames); if (err < 0) { if ((err = xrun_recovery(handle, err)) < 0) { printf("MMAP begin avail error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } first = 1; } printf("Callback %d %d\n", (int)offset, (int)frames); int i; for(i=0; i<frames; i++) *(__u8 *)(my_areas[0].addr + offset + i)=i%64; //generate_sine(my_areas, offset, frames, &sns->phase); commitres = snd_pcm_mmap_commit(handle, offset, frames); if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) { if ((err = xrun_recovery(handle, commitres >= 0 ? -EPIPE : commitres)) < 0) { printf("MMAP commit error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } first = 1; } size -= frames; } } }