Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* mic_alsa.cpp - this file is part of DeSmuME
- *
- * Copyright (C) 2009 DeSmuME Team
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
- #include <alsa/asoundlib.h>
- #include <glib.h>
- #include "types.h"
- #include "mic.h"
- #include "debug.h"
- #include "readwrite.h"
- #include "emufile.h"
- #include "utils/ringbuffer.h"
- #define MIC_BUFSIZE 4096
- BOOL Mic_Inited = FALSE;
- jack_ringbuffer_t * Mic_Buffer;
- int MicButtonPressed;
- static GThread *mic_reader;
- // Handle for the PCM device
- static snd_pcm_t *pcm_handle;
- static snd_pcm_uframes_t mic_bufsize;
- static gpointer snd_pcm_read(gpointer data)
- {
- int error;
- snd_pcm_sframes_t frames;
- char buf[MIC_BUFSIZE];
- while (Mic_Inited) {
- if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) {
- g_printerr("Failed to poll: %s\n", snd_strerror(error));
- continue;
- }
- error = snd_pcm_avail(pcm_handle);
- if (error == 0)
- continue;
- if (error == -EPIPE) {
- g_printerr("xrun! %s\n", snd_strerror(error));
- continue;
- //return GINT_TO_POINTER(FALSE);
- }
- if (error < 0) {
- g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error));
- continue;
- //return GINT_TO_POINTER(FALSE);
- }
- frames = error > mic_bufsize ? mic_bufsize : error;
- g_printerr ("frames: %ld\n", frames);
- memset(buf, 0, sizeof(buf));
- error = snd_pcm_readi(pcm_handle, buf, frames);
- if (error < 0)
- error = snd_pcm_recover(pcm_handle, error, 0);
- if (error < 0) {
- LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error));
- continue;
- //return GINT_TO_POINTER(FALSE);
- }
- jack_ringbuffer_write(Mic_Buffer, buf, frames);
- }
- return GINT_TO_POINTER(TRUE);
- }
- BOOL Mic_Init()
- {
- snd_pcm_hw_params_t *hwparams;
- snd_pcm_sw_params_t *swparams;
- snd_pcm_uframes_t periods;
- int err;
- if (Mic_Inited)
- return TRUE;
- if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
- g_printerr("Failed to open device: %s\n", snd_strerror(err));
- return FALSE;
- }
- /* Hardware params */
- snd_pcm_hw_params_alloca(&hwparams);
- if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
- g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
- g_printerr("Failed to set access: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) {
- g_printerr("Failed to set format: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) {
- g_printerr("Failed to set channels: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) {
- g_printerr("Failed to set rate: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
- g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &mic_bufsize)) < 0) {
- g_printerr("Failed to get buffer size: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_hw_params_get_period_size(hwparams, &periods, 0)) < 0) {
- g_printerr("Failed to get period size: %s\n", snd_strerror(err));
- return FALSE;
- }
- /* Software params */
- snd_pcm_sw_params_alloca(&swparams);
- if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) {
- g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, mic_bufsize)) < 0) {
- g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) {
- g_printerr("Failed to set start mode: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) {
- g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err));
- return FALSE;
- }
- if ((err = snd_pcm_prepare (pcm_handle)) < 0) {
- g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err));
- return FALSE;
- }
- Mic_Buffer = jack_ringbuffer_create(MIC_BUFSIZE);
- Mic_Inited = TRUE;
- mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL);
- return TRUE;
- }
- void Mic_Reset()
- {
- if (!Mic_Inited)
- return;
- jack_ringbuffer_reset(Mic_Buffer);
- }
- void Mic_DeInit()
- {
- if (!Mic_Inited)
- return;
- Mic_Inited = FALSE;
- g_thread_join(mic_reader);
- jack_ringbuffer_free(Mic_Buffer);
- snd_pcm_drop(pcm_handle);
- snd_pcm_close(pcm_handle);
- }
- u8 Mic_ReadSample()
- {
- char tmp;
- u8 ret;
- if (!Mic_Inited)
- return 0;
- jack_ringbuffer_read(Mic_Buffer, &tmp, 1);
- if (Mic_Buffer->read_ptr & 0x1) {
- ret = ((tmp & 0x1) << 7);
- } else {
- ret = ((tmp & 0xFE) >> 1);
- }
- return ret;
- }
- /* FIXME: stub! */
- void mic_savestate(EMUFILE* os)
- {
- write32le((u32)(-1),os);
- }
- bool mic_loadstate(EMUFILE* is, int size)
- {
- is->fseek(size, SEEK_CUR);
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement