Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  1/*
  2 *  Routines for Gravis UltraSound soundcards - Synthesizer
  3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  4 *
  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
 22#include <linux/time.h>
 23#include <sound/core.h>
 24#include <sound/gus.h>
 25
 26/*
 27 *
 28 */
 29
 30int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
 31			      char __user *data, long len, int atomic)
 32{
 33	struct snd_gus_card *gus = private_data;
 34	struct snd_gf1_mem_block *block;
 35	int err;
 36
 37	if (wave->format & IWFFFF_WAVE_ROM)
 38		return 0;	/* it's probably ok - verify the address? */
 39	if (wave->format & IWFFFF_WAVE_STEREO)
 40		return -EINVAL;	/* not supported */
 41	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
 42				  SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF,
 43				  NULL, wave->size,
 44				  wave->format & IWFFFF_WAVE_16BIT, 1,
 45				  wave->share_id);
 46	if (block == NULL)
 47		return -ENOMEM;
 48	err = snd_gus_dram_write(gus, data,
 49				 block->ptr, wave->size);
 50	if (err < 0) {
 51		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
 52		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
 53		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
 54		return err;
 55	}
 56	wave->address.memory = block->ptr;
 57	return 0;
 58}
 59
 60int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
 61			      char __user *data, long len, int atomic)
 62{
 63	struct snd_gus_card *gus = private_data;
 64
 65	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size,
 66				 wave->format & IWFFFF_WAVE_ROM ? 1 : 0);
 67}
 68
 69int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
 70				 int atomic)
 71{
 72	struct snd_gus_card *gus = private_data;
 73
 74	if (wave->format & IWFFFF_WAVE_ROM)
 75		return 0;	/* it's probably ok - verify the address? */	
 76	return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
 77}
 78
 79/*
 80 *
 81 */
 82
 83int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
 84			   char __user *data, long len, int atomic)
 85{
 86	struct snd_gus_card *gus = private_data;
 87	struct snd_gf1_mem_block *block;
 88	int err;
 89
 90	if (wave->format & GF1_WAVE_STEREO)
 91		return -EINVAL;	/* not supported */
 92	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
 93				  SNDRV_GF1_MEM_OWNER_WAVE_GF1,
 94				  NULL, wave->size,
 95				  wave->format & GF1_WAVE_16BIT, 1,
 96				  wave->share_id);
 97	if (block == NULL)
 98		return -ENOMEM;
 99	err = snd_gus_dram_write(gus, data,
100				 block->ptr, wave->size);
101	if (err < 0) {
102		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
103		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
104		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
105		return err;
106	}
107	wave->address.memory = block->ptr;
108	return 0;
109}
110
111int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
112			   char __user *data, long len, int atomic)
113{
114	struct snd_gus_card *gus = private_data;
115
116	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0);
117}
118
119int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
120			      int atomic)
121{
122	struct snd_gus_card *gus = private_data;
123
124	return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
125}
126
127/*
128 *
129 */
130
131int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
132			      char __user *data, long len, int atomic)
133{
134	struct snd_gus_card *gus = private_data;
135	struct snd_gf1_mem_block *block;
136	int err;
137
138	if (instr->format & SIMPLE_WAVE_STEREO)
139		return -EINVAL;	/* not supported */
140	block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
141				  SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE,
142				  NULL, instr->size,
143				  instr->format & SIMPLE_WAVE_16BIT, 1,
144				  instr->share_id);
145	if (block == NULL)
146		return -ENOMEM;
147	err = snd_gus_dram_write(gus, data, block->ptr, instr->size);
148	if (err < 0) {
149		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
150		snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
151		snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
152		return err;
153	}
154	instr->address.memory = block->ptr;
155	return 0;
156}
157
158int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
159			      char __user *data, long len, int atomic)
160{
161	struct snd_gus_card *gus = private_data;
162
163	return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0);
164}
165
166int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
167			         int atomic)
168{
169	struct snd_gus_card *gus = private_data;
170
171	return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory);
172}