1 /* 2 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> 3 * 4 * Routines for control of EMU WaveTable chip 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <sound/driver.h> 22 #include <linux/wait.h> 23 #include <linux/sched.h> 24 #include <linux/slab.h> 25 #include <linux/string.h> 26 #include <sound/core.h> 27 #include <sound/emux_synth.h> 28 #include <linux/init.h> 29 #include "emux_voice.h" 30 31 MODULE_AUTHOR("Takashi Iwai"); 32 MODULE_DESCRIPTION("Routines for control of EMU WaveTable chip"); 33 MODULE_LICENSE("GPL"); 34 35 /* 36 * create a new hardware dependent device for Emu8000/Emu10k1 37 */ 38 int snd_emux_new(snd_emux_t **remu) 39 { 40 snd_emux_t *emu; 41 42 *remu = NULL; 43 emu = kzalloc(sizeof(*emu), GFP_KERNEL); 44 if (emu == NULL) 45 return -ENOMEM; 46 47 spin_lock_init(&emu->voice_lock); 48 init_MUTEX(&emu->register_mutex); 49 50 emu->client = -1; 51 #ifdef CONFIG_SND_SEQUENCER_OSS 52 emu->oss_synth = NULL; 53 #endif 54 emu->max_voices = 0; 55 emu->use_time = 0; 56 57 init_timer(&emu->tlist); 58 emu->tlist.function = snd_emux_timer_callback; 59 emu->tlist.data = (unsigned long)emu; 60 emu->timer_active = 0; 61 62 *remu = emu; 63 return 0; 64 } 65 66 67 /* 68 */ 69 int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name) 70 { 71 int err; 72 snd_sf_callback_t sf_cb; 73 74 snd_assert(emu->hw != NULL, return -EINVAL); 75 snd_assert(emu->max_voices > 0, return -EINVAL); 76 snd_assert(card != NULL, return -EINVAL); 77 snd_assert(name != NULL, return -EINVAL); 78 79 emu->card = card; 80 emu->name = kstrdup(name, GFP_KERNEL); 81 emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL); 82 if (emu->voices == NULL) 83 return -ENOMEM; 84 85 /* create soundfont list */ 86 memset(&sf_cb, 0, sizeof(sf_cb)); 87 sf_cb.private_data = emu; 88 sf_cb.sample_new = (snd_sf_sample_new_t)emu->ops.sample_new; 89 sf_cb.sample_free = (snd_sf_sample_free_t)emu->ops.sample_free; 90 sf_cb.sample_reset = (snd_sf_sample_reset_t)emu->ops.sample_reset; 91 emu->sflist = snd_sf_new(&sf_cb, emu->memhdr); 92 if (emu->sflist == NULL) 93 return -ENOMEM; 94 95 if ((err = snd_emux_init_hwdep(emu)) < 0) 96 return err; 97 98 snd_emux_init_voices(emu); 99 100 snd_emux_init_seq(emu, card, index); 101 #ifdef CONFIG_SND_SEQUENCER_OSS 102 snd_emux_init_seq_oss(emu); 103 #endif 104 snd_emux_init_virmidi(emu, card); 105 106 #ifdef CONFIG_PROC_FS 107 snd_emux_proc_init(emu, card, index); 108 #endif 109 return 0; 110 } 111 112 113 /* 114 */ 115 int snd_emux_free(snd_emux_t *emu) 116 { 117 unsigned long flags; 118 119 if (! emu) 120 return -EINVAL; 121 122 spin_lock_irqsave(&emu->voice_lock, flags); 123 if (emu->timer_active) 124 del_timer(&emu->tlist); 125 spin_unlock_irqrestore(&emu->voice_lock, flags); 126 127 #ifdef CONFIG_PROC_FS 128 snd_emux_proc_free(emu); 129 #endif 130 snd_emux_delete_virmidi(emu); 131 #ifdef CONFIG_SND_SEQUENCER_OSS 132 snd_emux_detach_seq_oss(emu); 133 #endif 134 snd_emux_detach_seq(emu); 135 136 snd_emux_delete_hwdep(emu); 137 138 if (emu->sflist) 139 snd_sf_free(emu->sflist); 140 141 kfree(emu->voices); 142 kfree(emu->name); 143 kfree(emu); 144 return 0; 145 } 146 147 148 EXPORT_SYMBOL(snd_emux_new); 149 EXPORT_SYMBOL(snd_emux_register); 150 EXPORT_SYMBOL(snd_emux_free); 151 152 EXPORT_SYMBOL(snd_emux_terminate_all); 153 EXPORT_SYMBOL(snd_emux_lock_voice); 154 EXPORT_SYMBOL(snd_emux_unlock_voice); 155 156 /* soundfont.c */ 157 EXPORT_SYMBOL(snd_sf_linear_to_log); 158 159 160 /* 161 * INIT part 162 */ 163 164 static int __init alsa_emux_init(void) 165 { 166 return 0; 167 } 168 169 static void __exit alsa_emux_exit(void) 170 { 171 } 172 173 module_init(alsa_emux_init) 174 module_exit(alsa_emux_exit) 175