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

📄 smurfjam.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
字号:
/*================================================================== * smurfjam.c - TCP/IP jam with friends code * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * Based on network server/client for ALSA sequencer (aseqnet) *   ver.0.1 * * Copyright (C) 1999-2000 Takashi Iwai * * 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 <smurf@resonance.org> * Smurf homepage: http://www.resonance.org/smurf/ *==================================================================*/#include "config.h"#ifdef ALSA_SUPPORT#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <netinet/in.h>#include <netdb.h>#include <sys/asoundlib.h>#include <getopt.h>#include <signal.h>#include <gdk/gdk.h>#include "drivers/alsa.h"#include "drivers/seq_alsa.h"#include "i18n.h"#include "smurfjam.h"#include "util.h"/* * prototypes */static void server_make_connection (void);static void flush_writebuf (void);static char *get_writebuf (int len);static int copy_local_to_remote (void);static void copy_remote_to_local(gpointer data, gint fd,				 GdkInputCondition cond);/* static void throw_monkey_wrench (void); */#define DEFAULT_PORT	40002	/* default TCP port number */#define MAX_BUF_EVENTS	200	/* max number of ALSA events */#define MAX_CONNECTION	10	/* max number of connections */gboolean jam_inited = FALSE;gboolean jam_server_mode;static char *readbuf;static int max_rdlen;static char *writebuf;static int cur_wrlen, max_wrlen;static int sockfd;static int netfd[MAX_CONNECTION] = {[0 ... MAX_CONNECTION-1] = -1};static int cur_connected;static int jam_seqport;/* * allocate and initialize buffers */intjam_init (void){  int i;  if (jam_inited) return (OK);  for (i = 0; i < MAX_CONNECTION; i++)    {      if (netfd[i] < 0)	close (netfd[i]);    }  max_wrlen = MAX_BUF_EVENTS * sizeof (snd_seq_event_t);  max_rdlen = MAX_BUF_EVENTS * sizeof (snd_seq_event_t);  writebuf = g_malloc0 (max_wrlen);  readbuf = g_malloc0 (max_rdlen);  cur_wrlen = 0;  if (!seq_alsa_init ())    return (FAIL);  /* create a port */  jam_seqport = snd_seq_create_simple_port (seq_alsa_handle, "SmurfJam",					    SND_SEQ_PORT_CAP_READ |					    SND_SEQ_PORT_CAP_WRITE |					    SND_SEQ_PORT_CAP_SUBS_READ |					    SND_SEQ_PORT_CAP_SUBS_WRITE,					    SND_SEQ_PORT_TYPE_MIDI_GENERIC);  if (jam_seqport < 0)    return (logit (LogFubar | LogErrno, _("Failed to create ALSA port")));  gdk_input_add (seq_alsa_fd, GDK_INPUT_READ,		 (GdkInputFunction)copy_local_to_remote, NULL);  log_message ("SmurfJam sequencer opened: %d:%d\n",		snd_seq_client_id (seq_alsa_handle), jam_seqport);  jam_inited = TRUE;  return (OK);}/* * close all files */voidjam_close (void){  int i;  if (!jam_inited) return;  for (i = 0; i < MAX_CONNECTION; i++)    {      if (netfd[i] >= 0)	close (netfd[i]);    }  if (sockfd >= 0)    close (sockfd);  snd_seq_delete_simple_port (seq_alsa_handle, jam_seqport);  seq_alsa_close ();  jam_inited = FALSE;}/* * initialize network server */intjam_server (int port){  int curstate = 1;  struct sockaddr_in addr;  if (!jam_init ())    return (FAIL);  memset (&addr, 0, sizeof(addr));  addr.sin_family = AF_INET;  addr.sin_addr.s_addr = INADDR_ANY;  addr.sin_port = htons (port);  sockfd = socket (AF_INET, SOCK_STREAM, 0);  if (sockfd < 0)    return (logit (LogFubar | LogErrno, _("Failed to create socket")));  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));  /* the return value is ignored.. */  if (bind(sockfd, &addr, sizeof(addr)) < 0)    return (logit (LogFubar | LogErrno, _("Failed to bind to socket")));  if (listen(sockfd, 5) < 0)    return (logit (LogFubar | LogErrno, _("Unable to listen to socket")));  gdk_input_add (sockfd, GDK_INPUT_READ,		 (GdkInputFunction)server_make_connection, NULL);  cur_connected = 0;  jam_server_mode = TRUE;  return (OK);}/* * start connection on server */static voidserver_make_connection (void){  struct sockaddr_in addr;  int i;  int addr_len;  for (i = 0; i < MAX_CONNECTION; i++)    {      if (netfd[i] < 0)	break;    }  if (i >= MAX_CONNECTION)    {      logit (LogWarn, "SmurfJam Server: too many connections!");      return;    }  memset(&addr, 0, sizeof(addr));  addr_len = sizeof(addr);  netfd[i] = accept(sockfd, (struct sockaddr *)&addr, &addr_len);  if (netfd[i] < 0)    {      logit (LogWarn, "SmurfJam Server: Failed to accept connection");      return;    }  gdk_input_add (netfd[i], GDK_INPUT_READ,		 (GdkInputFunction)copy_remote_to_local, NULL);  log_message ("SmurfJam Server: accepted connection");  cur_connected++;}/* * initialize network client */intjam_client (char *server, int port){  struct sockaddr_in addr;  struct hostent *host;  int curstate = 1;  int fd;  if (!jam_init ())    return (FAIL);  if ((fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)    return (logit (LogFubar | LogErrno, _("Failed to create socket")));  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0)    return (logit (LogFubar | LogErrno, _("setsockopt failed")));  if ((host = gethostbyname(server)) == NULL)    return (logit (LogFubar, _("Can't get address for host %s"), server));  addr.sin_port = htons (port);  addr.sin_family = AF_INET;  memcpy (&addr.sin_addr, host->h_addr, host->h_length);  if (connect (fd, &addr, sizeof (addr)) < 0)    return (logit (LogFubar | LogErrno, _("Failed to connect")));  log_message (_("SmurfJam Client connected"));  netfd[0] = fd;  cur_connected = 1;  jam_server_mode = FALSE;  return (OK);}/* * flush write buffer - send data to the socket */static voidflush_writebuf (void){  if (cur_wrlen)    {      int i;      for (i = 0; i < MAX_CONNECTION; i++)	{	  if (netfd[i] >= 0)	    write(netfd[i], writebuf, cur_wrlen);	}      cur_wrlen = 0;    }}/* * get space from write buffer */static char *get_writebuf (int len){  char *buf;  if (cur_wrlen + len >= max_wrlen)    flush_writebuf();  buf = writebuf + cur_wrlen;  cur_wrlen += len;  return buf;}/* * copy events from sequencer to port(s) */static intcopy_local_to_remote (void){  int rc;  snd_seq_event_t *ev;  char *buf;  while ((rc = snd_seq_event_input(seq_alsa_handle, &ev)) >= 0 && ev)    {      if (ev->type >= SND_SEQ_EVENT_CLIENT_START &&	  ! snd_seq_ev_is_variable_type(ev))	{	  snd_seq_free_event(ev);	  continue;	}      if (snd_seq_ev_is_variable(ev))	{	  int len;	  len = sizeof(snd_seq_event_t) + ev->data.ext.len;	  buf = get_writebuf(len);	  memcpy(buf, ev, sizeof(snd_seq_event_t));	  memcpy(buf + sizeof(snd_seq_event_t), ev->data.ext.ptr,		 ev->data.ext.len);	}      else	{	  buf = get_writebuf(sizeof(snd_seq_event_t));	  memcpy(buf, ev, sizeof(snd_seq_event_t));	}      snd_seq_free_event(ev);    }  flush_writebuf();  return 0;}/* * copy events from a port to sequencer */static voidcopy_remote_to_local(gpointer data, gint fd, GdkInputCondition cond){  int count;  char *buf;  snd_seq_event_t *ev;  count = read(fd, readbuf, MAX_BUF_EVENTS * sizeof(snd_seq_event_t));  buf = readbuf;  if (count == 0)    {      fprintf(stderr, "disconnected\n");      return;    }  while (count > 0)    {      ev = (snd_seq_event_t*)buf;      buf += sizeof(snd_seq_event_t);      count -= sizeof(snd_seq_event_t);      if (snd_seq_ev_is_variable(ev) && ev->data.ext.len > 0)	{	  if (ev->type == SND_SEQ_EVENT_USR_VAR0)	    {	      fwrite (buf, ev->data.ext.len, 1, stdout);	      fflush (stdout);	    }	  ev->data.ext.ptr = buf;	  buf += ev->data.ext.len;	  count -= ev->data.ext.len;	}      snd_seq_ev_set_direct(ev);      snd_seq_ev_set_source(ev, jam_seqport);      snd_seq_ev_set_subs(ev);      snd_seq_event_output(seq_alsa_handle, ev);    }  snd_seq_drain_output(seq_alsa_handle);  return;}#if 0static voidthrow_monkey_wrench (void){  char buf[1024];  FILE *fd;  size_t count;  snd_seq_event_t ev;  fd = fopen ("/etc/services", "r");  count = fread (buf, 1, sizeof (buf), fd);  fclose (fd);  ev.type = SND_SEQ_EVENT_USR_VAR0;  snd_seq_ev_set_variable (&ev, count, buf);  snd_seq_ev_set_direct (&ev);  snd_seq_ev_set_source (&ev, 0);  snd_seq_ev_set_dest (&ev, snd_seq_client_id (seq_alsa_handle), 0);  snd_seq_event_output (seq_alsa_handle, &ev);#ifdef NEW_ALSA  snd_seq_drain_output (seq_alsa_handle);#else  snd_seq_flush_output (seq_alsa_handle);#endif}#endif#endif /* ALSA_SUPPORT */

⌨️ 快捷键说明

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