示例#1
0
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;

};
示例#2
0
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;
};