Want more features on Pastebin? Sign Up, it's FREE!
Guest

rm

By: a guest on Jan 11th, 2010  |  syntax: None  |  size: 6.06 KB  |  views: 46  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /* mic_alsa.cpp - this file is part of DeSmuME
  2.  *
  3.  * Copyright (C) 2009 DeSmuME Team
  4.  *
  5.  * This file is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2, or (at your option)
  8.  * any later version.
  9.  *
  10.  * This file is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; see the file COPYING.  If not, write to
  17.  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.  * Boston, MA 02111-1307, USA.
  19.  */
  20.  
  21. #include <alsa/asoundlib.h>
  22. #include <glib.h>
  23. #include "types.h"
  24. #include "mic.h"
  25. #include "debug.h"
  26. #include "readwrite.h"
  27. #include "emufile.h"
  28. #include "utils/ringbuffer.h"
  29.  
  30. #define MIC_BUFSIZE 4096
  31.  
  32. BOOL Mic_Inited = FALSE;
  33. jack_ringbuffer_t * Mic_Buffer;
  34. int MicButtonPressed;
  35.  
  36. static GThread *mic_reader;
  37.  
  38. // Handle for the PCM device
  39. static snd_pcm_t *pcm_handle;
  40. static snd_pcm_uframes_t mic_bufsize;
  41.  
  42. static gpointer snd_pcm_read(gpointer data)
  43. {
  44.   int error;
  45.   snd_pcm_sframes_t frames;
  46.   char buf[MIC_BUFSIZE];
  47.  
  48.   while (Mic_Inited) {
  49.  
  50.     if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) {
  51.         g_printerr("Failed to poll: %s\n", snd_strerror(error));
  52.         continue;
  53.     }
  54.  
  55.     error = snd_pcm_avail(pcm_handle);
  56.     if (error == 0)
  57.         continue;
  58.     if (error == -EPIPE) {
  59.         g_printerr("xrun! %s\n", snd_strerror(error));
  60.         continue;
  61.         //return GINT_TO_POINTER(FALSE);
  62.     }
  63.     if (error < 0) {
  64.         g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error));
  65.         continue;
  66.         //return GINT_TO_POINTER(FALSE);
  67.     }
  68.  
  69.     frames = error > mic_bufsize ? mic_bufsize : error;
  70.     g_printerr ("frames: %ld\n", frames);
  71.     memset(buf, 0, sizeof(buf));
  72.     error = snd_pcm_readi(pcm_handle, buf, frames);
  73.     if (error < 0)
  74.         error = snd_pcm_recover(pcm_handle, error, 0);
  75.     if (error < 0) {
  76.         LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error));
  77.         continue;
  78.         //return GINT_TO_POINTER(FALSE);
  79.     }
  80.     jack_ringbuffer_write(Mic_Buffer, buf, frames);
  81.   }
  82.  
  83.   return GINT_TO_POINTER(TRUE);
  84. }
  85.  
  86. BOOL Mic_Init()
  87. {
  88.     snd_pcm_hw_params_t *hwparams;
  89.     snd_pcm_sw_params_t *swparams;
  90.     snd_pcm_uframes_t periods;
  91.     int err;
  92.  
  93.     if (Mic_Inited)
  94.         return TRUE;
  95.  
  96.     if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
  97.         g_printerr("Failed to open device: %s\n", snd_strerror(err));
  98.         return FALSE;
  99.     }
  100.  
  101.     /* Hardware params */
  102.     snd_pcm_hw_params_alloca(&hwparams);
  103.     if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) {
  104.         g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err));
  105.         return FALSE;
  106.     }
  107.  
  108.     if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
  109.         g_printerr("Failed to set access: %s\n", snd_strerror(err));
  110.         return FALSE;
  111.     }
  112.  
  113.     if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) {
  114.         g_printerr("Failed to set format: %s\n", snd_strerror(err));
  115.         return FALSE;
  116.     }
  117.  
  118.     if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) {
  119.         g_printerr("Failed to set channels: %s\n", snd_strerror(err));
  120.         return FALSE;
  121.     }
  122.  
  123.     if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) {
  124.         g_printerr("Failed to set rate: %s\n", snd_strerror(err));
  125.         return FALSE;
  126.     }
  127.  
  128.     if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
  129.         g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err));
  130.         return FALSE;
  131.     }
  132.  
  133.     if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &mic_bufsize)) < 0) {
  134.         g_printerr("Failed to get buffer size: %s\n", snd_strerror(err));
  135.         return FALSE;
  136.     }
  137.  
  138.     if ((err = snd_pcm_hw_params_get_period_size(hwparams, &periods, 0)) < 0) {
  139.         g_printerr("Failed to get period size: %s\n", snd_strerror(err));
  140.         return FALSE;
  141.     }
  142.  
  143.     /* Software params */
  144.     snd_pcm_sw_params_alloca(&swparams);
  145.     if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) {
  146.         g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err));
  147.         return FALSE;
  148.     }
  149.  
  150.     if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, mic_bufsize)) < 0) {
  151.         g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err));
  152.         return FALSE;
  153.     }
  154.  
  155.     if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) {
  156.         g_printerr("Failed to set start mode: %s\n", snd_strerror(err));
  157.         return FALSE;
  158.     }
  159.  
  160.     if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) {
  161.         g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err));
  162.         return FALSE;
  163.     }
  164.  
  165.     if ((err = snd_pcm_prepare (pcm_handle)) < 0) {
  166.         g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err));
  167.         return FALSE;
  168.     }
  169.  
  170.     Mic_Buffer = jack_ringbuffer_create(MIC_BUFSIZE);
  171.     Mic_Inited = TRUE;
  172.  
  173.     mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL);
  174.  
  175.     return TRUE;
  176. }
  177.  
  178. void Mic_Reset()
  179. {
  180.     if (!Mic_Inited)
  181.         return;
  182.  
  183.     jack_ringbuffer_reset(Mic_Buffer);
  184. }
  185.  
  186. void Mic_DeInit()
  187. {
  188.     if (!Mic_Inited)
  189.         return;
  190.  
  191.     Mic_Inited = FALSE;
  192.  
  193.     g_thread_join(mic_reader);
  194.     jack_ringbuffer_free(Mic_Buffer);
  195.  
  196.     snd_pcm_drop(pcm_handle);
  197.     snd_pcm_close(pcm_handle);
  198. }
  199.  
  200. u8 Mic_ReadSample()
  201. {
  202.     char tmp;
  203.     u8 ret;
  204.  
  205.     if (!Mic_Inited)
  206.         return 0;
  207.  
  208.     jack_ringbuffer_read(Mic_Buffer, &tmp, 1);
  209.  
  210.     if (Mic_Buffer->read_ptr & 0x1) {
  211.         ret = ((tmp & 0x1) << 7);
  212.     } else {
  213.         ret = ((tmp & 0xFE) >> 1);
  214.     }
  215.  
  216.     return ret;
  217. }
  218.  
  219. /* FIXME: stub! */
  220. void mic_savestate(EMUFILE* os)
  221. {
  222.     write32le((u32)(-1),os);
  223. }
  224.  
  225. bool mic_loadstate(EMUFILE* is, int size)
  226. {
  227.     is->fseek(size, SEEK_CUR);
  228.     return TRUE;
  229. }
clone this paste RAW Paste Data