aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/oss/pcm_plugin.h
blob: a8a4f958043565dfbda0a93f196daf6d8c7e5c87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ifndef __PCM_PLUGIN_H
#define __PCM_PLUGIN_H

/*
 *  Digital Audio (Plugin interface) abstract layer
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   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
 *
 */

#ifdef CONFIG_SND_PCM_OSS_PLUGINS

#include <linux/bitmap.h>

static inline unsigned long *bitmap_alloc(unsigned int nbits)
{
	return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL);
}

#define snd_pcm_plug_stream(plug) ((plug)->stream)

enum snd_pcm_plugin_action {
	INIT = 0,
	PREPARE = 1,
};

struct snd_pcm_channel_area {
	void *addr;			/* base address of channel samples */
	unsigned int first;		/* offset to first sample in bits */
	unsigned int step;		/* samples distance in bits */
};

struct snd_pcm_plugin_channel {
	void *aptr;			/* pointer to the allocated area */
	struct snd_pcm_channel_area area;
	snd_pcm_uframes_t frames;	/* allocated frames */
	unsigned int enabled:1;		/* channel need to be processed */
	unsigned int wanted:1;		/* channel is wanted */
};

struct snd_pcm_plugin_format {
	int format;
	unsigned int rate;
	unsigned int channels;
};

struct snd_pcm_plugin {
	const char *name;		/* plug-in name */
	int stream;
	struct snd_pcm_plugin_format src_format;	/* source format */
	struct snd_pcm_plugin_format dst_format;	/* destination format */
	int src_width;			/* sample width in bits */
	int dst_width;			/* sample width in bits */
	int access;
	snd_pcm_sframes_t (*src_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames);
	snd_pcm_sframes_t (*dst_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t src_frames);
	snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
					     snd_pcm_uframes_t frames,
					     struct snd_pcm_plugin_channel **channels);
	int (*src_channels_mask)(struct snd_pcm_plugin *plugin,
				 unsigned long *dst_vmask,
				 unsigned long **src_vmask);
	int (*dst_channels_mask)(struct snd_pcm_plugin *plugin,
				 unsigned long *src_vmask,
				 unsigned long **dst_vmask);
	snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
				      const struct snd_pcm_plugin_channel *src_channels,
				      struct snd_pcm_plugin_channel *dst_channels,
				      snd_pcm_uframes_t frames);
	int (*action)(struct snd_pcm_plugin *plugin,
		      enum snd_pcm_plugin_action action,
		      unsigned long data);
	struct snd_pcm_plugin *prev;
	struct snd_pcm_plugin *next;
	struct snd_pcm_substream *plug;
	void *private_data;
	void (*private_free)(struct snd_pcm_plugin *plugin);
	char *buf;
	snd_pcm_uframes_t buf_frames;
	struct snd_pcm_plugin_channel *buf_channels;
	unsigned long *src_vmask;
	unsigned long *dst_vmask;
	char extra_data[0];
};

int snd_pcm_plugin_build(struct snd_pcm_substream *handle,
                         const char *name,
                         struct snd_pcm_plugin_format *src_format,
                         struct snd_pcm_plugin_format *dst_format,
                         size_t extra,
                         struct snd_pcm_plugin **ret);
int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin);
int snd_pcm_plugin_clear(struct snd_pcm_plugin **first);
int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size);
snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size);

#define FULL ROUTE_PLUGIN_RESOLUTION
#define HALF ROUTE_PLUGIN_RESOLUTION / 2

int snd_pcm_plugin_build_io(struct snd_pcm_substream *handle,
			    struct snd_pcm_hw_params *params,
			    struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_linear(struct snd_pcm_substream *handle,
				struct snd_pcm_plugin_format *src_format,
				struct snd_pcm_plugin_format *dst_format,
				struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *handle,
			       struct snd_pcm_plugin_format *src_format,
			       struct snd_pcm_plugin_format *dst_format,
			       struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
			      struct snd_pcm_plugin_format *src_format,
			      struct snd_pcm_plugin_format *dst_format,
			      struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
			       struct snd_pcm_plugin_format *src_format,
			       struct snd_pcm_plugin_format *dst_format,
			       int *ttable,
		               struct snd_pcm_plugin **r_plugin);
int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
			      struct snd_pcm_plugin_format *src_format,
			      struct snd_pcm_plugin_format *dst_format,
			      struct snd_pcm_plugin **r_plugin);

int snd_pcm_plug_format_plugins(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_pcm_hw_params *slave_params);

int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask);

int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin);

snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *handle,
					      struct snd_pcm_plugin_channel *src_channels,
					      snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *handle,
					     struct snd_pcm_plugin_channel *dst_channels_final,
					     snd_pcm_uframes_t size);

snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *handle,
						   char *buf, snd_pcm_uframes_t count,
						   struct snd_pcm_plugin_channel **channels);

snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
						 snd_pcm_uframes_t frames,
						 struct snd_pcm_plugin_channel **channels);

int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_channel,
			 size_t dst_offset,
			 size_t samples, int format);
int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel,
		      size_t src_offset,
		      const struct snd_pcm_channel_area *dst_channel,
		      size_t dst_offset,
		      size_t samples, int format);

void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size);
void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr);
snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream,
				     const char *ptr, snd_pcm_uframes_t size,
				     int in_kernel);
snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream,
				    char *ptr, snd_pcm_uframes_t size, int in_kernel);
snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream,
				      void **bufs, snd_pcm_uframes_t frames,
				      int in_kernel);
snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
				     void **bufs, snd_pcm_uframes_t frames,
				     int in_kernel);

#define ROUTE_PLUGIN_RESOLUTION 16

int getput_index(int format);
int copy_index(int format);
int conv_index(int src_format, int dst_format);

void zero_channel(struct snd_pcm_plugin *plugin,
		  const struct snd_pcm_plugin_channel *dst_channel,
		  size_t samples);

#else

static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; }

#endif

#ifdef PLUGIN_DEBUG
#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args)
#else
#define pdprintf( fmt, args... ) 
#endif

#endif				/* __PCM_PLUGIN_H */