⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm_alsa.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
字号:
/*================================================================== * pcm_alsa.c - ALSA PCM audio support * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * This program 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 * of the License, or (at your option) any later version. * * This program 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include "config.h"/* currently disabled */#if 0#ifdef ALSA_SUPPORT#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <glib.h>#include <gdk/gdk.h>#include <sys/poll.h>#include "alsa.h"#include "pcm.h"#include "pcm_alsa.h"#include "smurfcfg.h"#include "util.h"#include "i18n.h"#include <sys/asoundlib.h>#define PCM_ALSA_NUM_CHUNKS 2#define PCM_ALSA_CHUNK_SIZE 50000static void pcm_alsa_play_callback (void);static gint pcm_alsa_set_params (gint width, gint signd, gint chans, gint rate);gboolean pcm_alsa_active = FALSE;static snd_pcm_t *pcm_alsa_handle;static gint pcm_alsa_card = 0;static gint pcm_alsa_device = 0;static snd_pcm_format_t pcm_format;static gint pcm_channels;static gint bits_per_sample;static gint bytes_per_frame;static gint buffer_size;static gint chunk_size;static gint chunk_bytes;static void *audio_buffer;static gint pcm_fd;static gint pcm_outptag;PCMPlayBackFunc *pcm_play_func;/* get the configuration file values for ALSA PCM */voidpcm_alsa_load_config (void){}#ifdef NEW_ALSA			/* New ALSA PCM API */gintpcm_alsa_play (gint width, gboolean signd, gint chans, gint rate,	       PCMPlayBackFunc *play_func){  struct pollfd pfd;  gint err;  gchar *s;  s = g_strdup_printf ("hw:%d,%d", pcm_alsa_card, pcm_alsa_device);  err = snd_pcm_open(&pcm_alsa_handle, s, SND_PCM_STREAM_PLAYBACK,		     SND_PCM_NONBLOCK);  g_free (s);  if (err < 0)    return (logit (LogFubar, _("Failed to open ALSA audio interface: %s"),		  snd_strerror (err)));  if ((err = snd_pcm_nonblock (pcm_alsa_handle, TRUE)) < 0)    {      snd_pcm_close (pcm_alsa_handle);      return (logit (LogFubar, _("Failed to set ALSA audio to non-blocking: %s"),		    snd_strerror (err)));    }  /* set format params */  if (!pcm_alsa_set_params (width, signd, chans, rate))    {      snd_pcm_close (pcm_alsa_handle);      return (FAIL);    }  /* allocate audio chunk buffer (fraction of total audio buffer) */  audio_buffer = g_malloc0 (chunk_bytes);  /* get the file descriptor for the opened PCM device */  err = snd_pcm_poll_descriptors (pcm_alsa_handle, &pfd, 1);  if (err <= 0 || !(pfd.events & POLLOUT))    {      snd_pcm_close (pcm_alsa_handle);      return (logit (LogFubar, _("Failed to get ALSA PCM file descriptor: %s"),			       snd_strerror (err)));    }  pcm_fd = pfd.fd;  pcm_play_func = play_func;  pcm_outptag = gdk_input_add (pcm_fd, GDK_INPUT_WRITE,			       (GdkInputFunction)pcm_alsa_play_callback,			       NULL);  pcm_alsa_active = TRUE;  return (OK);}static voidpcm_alsa_play_callback (void){  gint count;  gint err;  if (!pcm_alsa_active) return;  count = (*pcm_play_func)(chunk_size, audio_buffer);  if (count == -1) {    pcm_alsa_stop ();    return;  }  if (count < chunk_size)    snd_pcm_format_set_silence (pcm_format, audio_buffer				+ bytes_per_frame * count,				(chunk_size - count) * pcm_channels);  err = snd_pcm_writei (pcm_alsa_handle, audio_buffer, chunk_size);  if (err == -EPIPE)		/* XRUN occured? */    {      if ((err = snd_pcm_prepare (pcm_alsa_handle) < 0))	{	  pcm_alsa_stop ();	  logit (LogFubar, _("ALSA PCM: Failed to recover from an underrun: %s"),			    snd_strerror (err));	  return;	}    }  else if (err < 0)    {      pcm_alsa_stop ();      logit (LogFubar, _("ALSA PCM write error: %s"), snd_strerror (err));      return;    }}voidpcm_alsa_stop (void){  if (!pcm_alsa_active) return;  gdk_input_remove (pcm_outptag);  snd_pcm_close (pcm_alsa_handle);}static gintpcm_alsa_set_params (gint width, gint signd, gint chans, gint rate){  snd_pcm_hw_params_t *params;  snd_pcm_sw_params_t *swparams;  snd_pcm_hw_params_alloca (&params);  snd_pcm_sw_params_alloca (&swparams);  if (snd_pcm_hw_params_any (pcm_alsa_handle, params) < 0)    return (logit (LogFubar, _("ALSA PCM: device has no available options")));  if (snd_pcm_hw_params_set_access (pcm_alsa_handle, params,				    SND_PCM_ACCESS_RW_INTERLEAVED) < 0)    return (logit (LogFubar, _("ALSA PCM: interleaved access not available")));  switch (width)    {    case 8:      if (signd) pcm_format = SND_PCM_FORMAT_S8;      else pcm_format = SND_PCM_FORMAT_U8;      break;    case 16:      if (signd) pcm_format = SND_PCM_FORMAT_S16;      else pcm_format = SND_PCM_FORMAT_U16;      break;    default:      return (logit (LogFubar, _("Invalid bit width '%d'"), width));    }  if (snd_pcm_hw_params_set_format (pcm_alsa_handle, params, pcm_format) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set sample format")));  if (snd_pcm_hw_params_set_channels (pcm_alsa_handle, params, chans) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set number of channels")));  if (snd_pcm_hw_params_set_rate_near (pcm_alsa_handle, params, rate, NULL) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set sampling rate")));  if (snd_pcm_hw_params_set_buffer_time_near (pcm_alsa_handle, params,		       PCM_ALSA_CHUNK_SIZE * PCM_ALSA_NUM_CHUNKS, NULL) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set buffer size")));  if (snd_pcm_hw_params_set_period_time_near (pcm_alsa_handle, params,					      PCM_ALSA_CHUNK_SIZE, NULL) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set buffer fragment size")));  if (snd_pcm_hw_params (pcm_alsa_handle, params) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set hardware parameters")));  buffer_size = snd_pcm_hw_params_get_buffer_size (params);  chunk_size = snd_pcm_hw_params_get_period_size (params, NULL);  snd_pcm_sw_params_current (pcm_alsa_handle, swparams);  if (snd_pcm_sw_params_set_xrun_mode (pcm_alsa_handle, swparams,  				       SND_PCM_XRUN_STOP) < 0)    return (logit (LogFubar, _("ALSA PCM: Failed to set xrun mode")));  snd_pcm_sw_params (pcm_alsa_handle, swparams);  bits_per_sample = snd_pcm_format_physical_width (pcm_format);  bytes_per_frame = chans * bits_per_sample / 8;  chunk_bytes = chunk_size * bytes_per_frame;  pcm_channels = chans;  return (OK);}#else  /* !NEW_ALSA - Older ALSA 0.5.x API */gintpcm_alsa_play (gint width, gboolean signd, gint chans, gint rate,	       PCMPlayBackFunc *play_func){  return (OK);}voidpcm_alsa_stop (void){}#endif /* #else !NEW_ALSA */#endif /* #ifdef ALSA_SUPPORT */#endif /* temporarily disabled */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -