Advertisement
Guest User

rm

a guest
Jan 11th, 2010
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.06 KB | None | 0 0
  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. }
  230.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement