void AudioDriverALSA::thread_func(void* p_udata) { AudioDriverALSA* ad = (AudioDriverALSA*)p_udata; while (!ad->exit_thread) { if (!ad->active) { for (unsigned int i=0; i < ad->period_size*ad->channels; i++) { ad->samples_out[i] = 0; }; } else { ad->lock(); ad->audio_server_process(ad->period_size, ad->samples_in); ad->unlock(); for(unsigned int i=0;i<ad->period_size*ad->channels;i++) { ad->samples_out[i]=ad->samples_in[i]>>16; } }; int todo = ad->period_size; int total = 0; while (todo) { if (ad->exit_thread) break; uint8_t* src = (uint8_t*)ad->samples_out; int wrote = snd_pcm_writei(ad->pcm_handle, (void*)(src + (total*ad->channels)), todo); if (wrote < 0) { if (ad->exit_thread) break; if ( wrote == -EAGAIN ) { //can't write yet (though this is blocking..) usleep(1000); continue; } wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0); if ( wrote < 0 ) { //absolute fail fprintf(stderr, "ALSA failed and can't recover: %s\n", snd_strerror(wrote)); ad->active=false; ad->exit_thread=true; break; } continue; }; total += wrote; todo -= wrote; }; }; ad->thread_exited=true; };
void AudioDriverALSA::thread_func(void *p_udata) { AudioDriverALSA *ad = (AudioDriverALSA *)p_udata; while (!ad->exit_thread) { ad->lock(); ad->start_counting_ticks(); if (!ad->active) { for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) { ad->samples_out[i] = 0; } } else { ad->audio_server_process(ad->period_size, ad->samples_in.ptrw()); for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) { ad->samples_out[i] = ad->samples_in[i] >> 16; } } int todo = ad->period_size; int total = 0; while (todo && !ad->exit_thread) { uint8_t *src = (uint8_t *)ad->samples_out.ptr(); int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo); if (wrote > 0) { total += wrote; todo -= wrote; } else if (wrote == -EAGAIN) { ad->stop_counting_ticks(); ad->unlock(); OS::get_singleton()->delay_usec(1000); ad->lock(); ad->start_counting_ticks(); } else { wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0); if (wrote < 0) { ERR_PRINTS("ALSA: Failed and can't recover: " + String(snd_strerror(wrote))); ad->active = false; ad->exit_thread = true; } } } // User selected a new device, finish the current one so we'll init the new device if (ad->device_name != ad->new_device) { ad->device_name = ad->new_device; ad->finish_device(); Error err = ad->init_device(); if (err != OK) { ERR_PRINT("ALSA: init_device error"); ad->device_name = "Default"; ad->new_device = "Default"; err = ad->init_device(); if (err != OK) { ad->active = false; ad->exit_thread = true; } } } ad->stop_counting_ticks(); ad->unlock(); }; ad->thread_exited = true; };