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

📄 wtbl_awepatch.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
📖 第 1 页 / 共 2 页
字号:
/*================================================================== * wtbl_awepatch.c - OSS AWE driver patch loading * Based on the awesfx utility Copyright (C) 1996-1999 Takashi Iwai * * 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"#ifdef AWE_SUPPORT/* #define AWEDRV_DEBUG 1 */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>#include <string.h>		/* for memmove, realloc and memset */#if defined(HAVE_SYS_SOUNDCARD_H)#include <sys/soundcard.h>#elif defined(HAVE_MACHINE_SOUNDCARD_H)#include <machine/soundcard.h>#endif#if defined(HAVE_AWE_VOICE_H)#include <awe_voice.h>#elif defined(HAVE_SYS_AWE_VOICE_H)#include <sys/awe_voice.h>#elif defined(HAVE_LINUX_AWE_VOICE_H)#include <linux/awe_voice.h>#endif#include <glib.h>#include "wtbl_awe.h"#include "wavetable.h"#include "seq_oss.h"#include "wtbl_aweunits.h"#include "sample.h"#include "sfont.h"#include "util.h"#include "i18n.h"/* size of blank loop for single shot voices */#define BLANK_LOOPSIZE		12#define BLANK_LOOPSTART		4#define BLANK_LOOPEND		8/* keeps track of cached sample data (one structure for each   SFSamDataInfo), one ID for sample data in the locked sound font and   another ID for temporary (unlocked) sample data. Locked/unlocked   sample data has to be loaded in separate AWE driver sound fonts in   order to use the AWE_REMOVE_LAST_SAMPLES feature. */typedef struct _AwePatchIDs{  gint locked_id;  gint unlocked_id;} AwePatchIDs;#define PATCHIDS_CHUNK_OPTIMUM_AREA 64/* memory chunk for AwePatchIDs structures */GMemChunk *chunk_patchids = NULL;/* set by awe_open_patch to the sample locking mode requested, so other routines   know what mode we're in */gboolean awe_lock_samples = FALSE;gint awe_patch_id_counter = 0;static gint awe_assign_patch_id (SFSample *sam);static void awe_clear_patch_ids (gboolean cacheonly);static gint load_patch (void *patch, gint len);static void awe_stuff_voicenfo (SFData * sf, SFSample * sp,  awe_voice_info * vp, SFGenAmount * garr);static void set_sample_info (SFData * sf, SFSample * sp, awe_voice_info * vp,  SFGenAmount * garr);static void set_init_info (awe_voice_info * vp, SFGenAmount * garr);static void set_rootkey (SFData * sf, SFSample * sp, awe_voice_info * vp,  SFGenAmount * garr);static void set_modenv (awe_voice_info * vp, SFGenAmount * garr);static void set_volenv (awe_voice_info * vp, SFGenAmount * garr);static void set_lfo1 (awe_voice_info * vp, SFGenAmount * garr);static void set_lfo2 (awe_voice_info * vp, SFGenAmount * garr);#define ASC_TO_KEY(c) ((c) - 'A' + 1)gintawe_open_patch(gboolean locksamples) { /* Send an "OPEN" patch block to awe */  struct open_patch_rec {    awe_patch_info hdr;    awe_open_parm parm;  } rec;  static unsigned char id_head[] = {    ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'), 0,    's', 'm', 'u', 'r', 'f'  };#ifdef AWEDRV_DEBUG  printf ("awe_open_patch (locksamples = %d)\n", locksamples);#endif  memset(&rec.parm.name, 0, AWE_PATCH_NAME_LEN);  memcpy(&rec.parm.name, id_head, sizeof (id_head));  /* to separate locked/unlocked samples into 2 separate sound fonts, sound     font name will be different for both locking modes */  rec.parm.name[sizeof (id_head)] = (gchar)(locksamples != 0);  rec.hdr.type = AWE_OPEN_PATCH;  rec.hdr.len = AWE_OPEN_PARM_SIZE;  /* sample locking and sharing flags */  rec.parm.type = (wtbl_cache_samples ? AWE_PAT_SHARED : AWE_PAT_TYPE_MISC)    | (locksamples ? 0x100 : 0);  rec.parm.reserved = 0;  /* remember sample lock mode for this patch open (for other routines) */  awe_lock_samples = locksamples;  if (!load_patch (&rec, sizeof (rec)))    return (logit (LogFubar | LogErrno, _("Open AWE patch failed")));  return (OK);}gintawe_close_patch (void){				/* Send a "CLOSE" patch block to awe */  struct awe_patch_info hdr;#ifdef AWEDRV_DEBUG  printf ("awe_close_patch ()\n");#endif  hdr.type = AWE_CLOSE_PATCH;  hdr.len = 0;  if (!load_patch (&hdr, sizeof (hdr)))    return (logit (LogFubar | LogErrno, _("Close AWE patch failed")));  return (OK);}typedef struct _sample_patch{  awe_patch_info hdr;  awe_sample_info sam;  gint16 data[0];} sample_patch;/* loads a sample patch */gintawe_load_sample (SFSample * sam, SFData * sf){  sample_patch *rec;  AwePatchIDs *patchids;  gint size;			/* sample size, in samples */  gint16 *p;  patchids = sam->datainfo->patchid;#ifdef AWEDRV_DEBUG  printf ("awe_load_sample (%s, patchids = %d, %d)\n", sam->name,	  patchids ? patchids->locked_id : -1,	  patchids ? patchids->unlocked_id : -1);#endif  /* sample already loaded for this locking mode? */  if (patchids && (awe_lock_samples ? patchids->locked_id		   : patchids->unlocked_id) != -1)    return (OK);  if (sam->sampletype & 0x8000)    size = 0;			/* rom sample? */  else    size = sam->datainfo->size + BLANK_LOOPSIZE;  /* alloc mem for patch and sample data */  if (!(rec =      (sample_patch *) safe_malloc (sizeof (sample_patch) + size * 2)))    return (FAIL);  rec->hdr.type = AWE_LOAD_DATA;  rec->hdr.len = AWE_SAMPLE_INFO_SIZE + size * 2;  rec->hdr.optarg = 0;  /* assign unique sample data ID */  rec->sam.sample = awe_assign_patch_id (sam);  rec->sam.size = size;  if (size)    {      rec->sam.start = 0;      rec->sam.end = size;      rec->sam.loopstart = sam->loopstart;      rec->sam.loopend = sam->loopend;    }  else  /* ROM sample */    {      rec->sam.start = sam->datainfo->start;	/* start is position in ROM */      rec->sam.end = sam->end + 1 + sam->datainfo->start;      rec->sam.loopstart = sam->loopstart + sam->datainfo->start;      rec->sam.loopend = sam->loopend + sam->datainfo->start;    }  rec->sam.mode_flags = 0;	/* | */  rec->sam.sf_id = 0;		/* | */  rec->sam.checksum_flag = 0;	/* + not used */  rec->sam.checksum = 0;	/* | */  if (size > 0)    {				/* load sample if its not in ROM */      if (!sam_load_sample (sam, size - BLANK_LOOPSIZE, 0, &rec->data))	{	  free (rec);	  return (FAIL);	}      /* blank loop */      p = rec->data + size - BLANK_LOOPSIZE;      memset (p, 0, BLANK_LOOPSIZE * 2);    }  if (!load_patch (rec, sizeof (sample_patch) + size * 2))    {      free (rec);      return (logit (LogFubar | LogErrno, _("Sample load failed")));    }  free (rec);  return (OK);}/* loads voice (instrument) information */gintawe_load_patch_info (gint bank, gint prenum, SFGenAmount *gens, SFSample *sam,		     SFData *sf, gboolean replace){  struct  {    awe_patch_info hdr;    awe_voice_rec_hdr vrec;    awe_voice_info vinfo;  } ip;				/* patch info/voice hdr/voice nfo */#ifdef AWEDRV_DEBUG  AwePatchIDs *patchids = sam->datainfo->patchid;  printf ("awe_load_patch_info (bank = %d, prenum = %d, sam = %s (%d, %d))\n",	  bank, prenum, sam->name,	  patchids ? patchids->locked_id : -1,	  patchids ? patchids->unlocked_id : -1);#endif  ip.hdr.type = AWE_LOAD_INFO;  ip.hdr.len = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE;  ip.hdr.optarg = 0;  ip.hdr.reserved = 0;  ip.vrec.bank = bank;  ip.vrec.instr = prenum;  ip.vrec.nvoices = 1;  ip.vrec.write_mode = replace ? AWE_WR_REPLACE : AWE_WR_APPEND;  awe_stuff_voicenfo (sf, sam, &ip.vinfo, gens); /* SF->AWE units */  if (!load_patch (&ip, sizeof (ip)))    return (logit (LogFubar | LogErrno, _("Zone info load failed")));  return (OK);}/* clear all samples */gintawe_clear_samples (void){#ifdef AWEDRV_DEBUG  printf ("awe_clear_samples ()\n");#endif  awe_clear_patch_ids (FALSE);  /* clear all patch IDs */  if (ioctl (seq_oss_fd, SNDCTL_SEQ_RESETSAMPLES, &seq_oss_dev) == -1)    return (logit (LogFubar | LogErrno, _("Failed to clear samples")));  return (OK);}/* removes all non-locked (cached) samples */gintawe_clear_unlocked_samples (void){#ifdef AWEDRV_DEBUG  printf ("awe_clear_unlocked_samples ()\n");#endif  awe_clear_patch_ids (TRUE);	/* clear unlocked patch IDs only */  AWE_REMOVE_LAST_SAMPLES (seq_oss_fd, seq_oss_dev);  return (OK);}/* generate and assign a new patch ID to a sample data info structure */static gintawe_assign_patch_id (SFSample *sam){  AwePatchIDs *patchids;  gint newid;  /* AwePatchIDs structure been allocated yet for this SFSamDataInfo? */  if (!sam->datainfo->patchid)    {      /* if GMemChunk hasn't been created yet, do so */      if (!chunk_patchids)	chunk_patchids =	  g_mem_chunk_create (AwePatchIDs, PATCHIDS_CHUNK_OPTIMUM_AREA,			      G_ALLOC_AND_FREE);

⌨️ 快捷键说明

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