18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Midi synth routines for the Emu8k/Emu10k1
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 1999 Steve Ratcliffe
68c2ecf20Sopenharmony_ci *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  Contains code based on awe_wave.c by Takashi Iwai
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "emux_voice.h"
128c2ecf20Sopenharmony_ci#include <linux/slab.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifdef SNDRV_EMUX_USE_RAW_EFFECT
158c2ecf20Sopenharmony_ci/*
168c2ecf20Sopenharmony_ci * effects table
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#define xoffsetof(type,tag)	((long)(&((type)NULL)->tag) - (long)(NULL))
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#define parm_offset(tag)	xoffsetof(struct soundfont_voice_parm *, tag)
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define PARM_IS_BYTE		(1 << 0)
248c2ecf20Sopenharmony_ci#define PARM_IS_WORD		(1 << 1)
258c2ecf20Sopenharmony_ci#define PARM_IS_ALIGNED		(3 << 2)
268c2ecf20Sopenharmony_ci#define PARM_IS_ALIGN_HI	(1 << 2)
278c2ecf20Sopenharmony_ci#define PARM_IS_ALIGN_LO	(2 << 2)
288c2ecf20Sopenharmony_ci#define PARM_IS_SIGNED		(1 << 4)
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define PARM_WORD	(PARM_IS_WORD)
318c2ecf20Sopenharmony_ci#define PARM_BYTE_LO	(PARM_IS_BYTE|PARM_IS_ALIGN_LO)
328c2ecf20Sopenharmony_ci#define PARM_BYTE_HI	(PARM_IS_BYTE|PARM_IS_ALIGN_HI)
338c2ecf20Sopenharmony_ci#define PARM_BYTE	(PARM_IS_BYTE)
348c2ecf20Sopenharmony_ci#define PARM_SIGN_LO	(PARM_IS_BYTE|PARM_IS_ALIGN_LO|PARM_IS_SIGNED)
358c2ecf20Sopenharmony_ci#define PARM_SIGN_HI	(PARM_IS_BYTE|PARM_IS_ALIGN_HI|PARM_IS_SIGNED)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic struct emux_parm_defs {
388c2ecf20Sopenharmony_ci	int type;	/* byte or word */
398c2ecf20Sopenharmony_ci	int low, high;	/* value range */
408c2ecf20Sopenharmony_ci	long offset;	/* offset in parameter record (-1 = not written) */
418c2ecf20Sopenharmony_ci	int update;	/* flgas for real-time update */
428c2ecf20Sopenharmony_ci} parm_defs[EMUX_NUM_EFFECTS] = {
438c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0},	/* env1 delay */
448c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0},	/* env1 attack */
458c2ecf20Sopenharmony_ci	{PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0},	/* env1 hold */
468c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0},	/* env1 decay */
478c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0},	/* env1 release */
488c2ecf20Sopenharmony_ci	{PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0},	/* env1 sustain */
498c2ecf20Sopenharmony_ci	{PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0},	/* env1 pitch */
508c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0},	/* env1 fc */
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0},	/* env2 delay */
538c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0},	/* env2 attack */
548c2ecf20Sopenharmony_ci	{PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0},	/* env2 hold */
558c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0},	/* env2 decay */
568c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0},	/* env2 release */
578c2ecf20Sopenharmony_ci	{PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0},	/* env2 sustain */
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0},	/* lfo1 delay */
608c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},	/* lfo1 freq */
618c2ecf20Sopenharmony_ci	{PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},	/* lfo1 vol */
628c2ecf20Sopenharmony_ci	{PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},	/* lfo1 pitch */
638c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},	/* lfo1 cutoff */
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0},	/* lfo2 delay */
668c2ecf20Sopenharmony_ci	{PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},	/* lfo2 freq */
678c2ecf20Sopenharmony_ci	{PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},	/* lfo2 pitch */
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH},	/* initial pitch */
708c2ecf20Sopenharmony_ci	{PARM_BYTE, 0, 0xff, parm_offset(chorus), 0},	/* chorus */
718c2ecf20Sopenharmony_ci	{PARM_BYTE, 0, 0xff, parm_offset(reverb), 0},	/* reverb */
728c2ecf20Sopenharmony_ci	{PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME},	/* cutoff */
738c2ecf20Sopenharmony_ci	{PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q},	/* resonance */
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* sample start */
768c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* loop start */
778c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* loop end */
788c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* coarse sample start */
798c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* coarse loop start */
808c2ecf20Sopenharmony_ci	{PARM_WORD, 0, 0xffff, -1, 0},	/* coarse loop end */
818c2ecf20Sopenharmony_ci	{PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME},	/* initial attenuation */
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* set byte effect value */
858c2ecf20Sopenharmony_cistatic void
868c2ecf20Sopenharmony_cieffect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
878c2ecf20Sopenharmony_ci{
888c2ecf20Sopenharmony_ci	short effect;
898c2ecf20Sopenharmony_ci	struct snd_emux_effect_table *fx = chan->private;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	effect = fx->val[type];
928c2ecf20Sopenharmony_ci	if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
938c2ecf20Sopenharmony_ci		if (parm_defs[type].type & PARM_IS_SIGNED)
948c2ecf20Sopenharmony_ci			effect += *(char*)valp;
958c2ecf20Sopenharmony_ci		else
968c2ecf20Sopenharmony_ci			effect += *valp;
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci	if (effect < parm_defs[type].low)
998c2ecf20Sopenharmony_ci		effect = parm_defs[type].low;
1008c2ecf20Sopenharmony_ci	else if (effect > parm_defs[type].high)
1018c2ecf20Sopenharmony_ci		effect = parm_defs[type].high;
1028c2ecf20Sopenharmony_ci	*valp = (unsigned char)effect;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/* set word effect value */
1068c2ecf20Sopenharmony_cistatic void
1078c2ecf20Sopenharmony_cieffect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci	int effect;
1108c2ecf20Sopenharmony_ci	struct snd_emux_effect_table *fx = chan->private;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	effect = *(unsigned short*)&fx->val[type];
1138c2ecf20Sopenharmony_ci	if (fx->flag[type] == EMUX_FX_FLAG_ADD)
1148c2ecf20Sopenharmony_ci		effect += *valp;
1158c2ecf20Sopenharmony_ci	if (effect < parm_defs[type].low)
1168c2ecf20Sopenharmony_ci		effect = parm_defs[type].low;
1178c2ecf20Sopenharmony_ci	else if (effect > parm_defs[type].high)
1188c2ecf20Sopenharmony_ci		effect = parm_defs[type].high;
1198c2ecf20Sopenharmony_ci	*valp = (unsigned short)effect;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci/* address offset */
1238c2ecf20Sopenharmony_cistatic int
1248c2ecf20Sopenharmony_cieffect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	int addr = 0;
1278c2ecf20Sopenharmony_ci	struct snd_emux_effect_table *fx = chan->private;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	if (fx->flag[hi])
1308c2ecf20Sopenharmony_ci		addr = (short)fx->val[hi];
1318c2ecf20Sopenharmony_ci	addr = addr << 15;
1328c2ecf20Sopenharmony_ci	if (fx->flag[lo])
1338c2ecf20Sopenharmony_ci		addr += (short)fx->val[lo];
1348c2ecf20Sopenharmony_ci	if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
1358c2ecf20Sopenharmony_ci		addr /= 2;
1368c2ecf20Sopenharmony_ci	return addr;
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
1408c2ecf20Sopenharmony_ci/* change effects - for OSS sequencer compatibility */
1418c2ecf20Sopenharmony_civoid
1428c2ecf20Sopenharmony_cisnd_emux_send_effect_oss(struct snd_emux_port *port,
1438c2ecf20Sopenharmony_ci			 struct snd_midi_channel *chan, int type, int val)
1448c2ecf20Sopenharmony_ci{
1458c2ecf20Sopenharmony_ci	int mode;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	if (type & 0x40)
1488c2ecf20Sopenharmony_ci		mode = EMUX_FX_FLAG_OFF;
1498c2ecf20Sopenharmony_ci	else if (type & 0x80)
1508c2ecf20Sopenharmony_ci		mode = EMUX_FX_FLAG_ADD;
1518c2ecf20Sopenharmony_ci	else
1528c2ecf20Sopenharmony_ci		mode = EMUX_FX_FLAG_SET;
1538c2ecf20Sopenharmony_ci	type &= 0x3f;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	snd_emux_send_effect(port, chan, type, val, mode);
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci#endif
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/* Modify the effect value.
1608c2ecf20Sopenharmony_ci * if update is necessary, call emu8000_control
1618c2ecf20Sopenharmony_ci */
1628c2ecf20Sopenharmony_civoid
1638c2ecf20Sopenharmony_cisnd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
1648c2ecf20Sopenharmony_ci		     int type, int val, int mode)
1658c2ecf20Sopenharmony_ci{
1668c2ecf20Sopenharmony_ci	int i;
1678c2ecf20Sopenharmony_ci	int offset;
1688c2ecf20Sopenharmony_ci	unsigned char *srcp, *origp;
1698c2ecf20Sopenharmony_ci	struct snd_emux *emu;
1708c2ecf20Sopenharmony_ci	struct snd_emux_effect_table *fx;
1718c2ecf20Sopenharmony_ci	unsigned long flags;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	emu = port->emu;
1748c2ecf20Sopenharmony_ci	fx = chan->private;
1758c2ecf20Sopenharmony_ci	if (emu == NULL || fx == NULL)
1768c2ecf20Sopenharmony_ci		return;
1778c2ecf20Sopenharmony_ci	if (type < 0 || type >= EMUX_NUM_EFFECTS)
1788c2ecf20Sopenharmony_ci		return;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	fx->val[type] = val;
1818c2ecf20Sopenharmony_ci	fx->flag[type] = mode;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	/* do we need to modify the register in realtime ? */
1848c2ecf20Sopenharmony_ci	if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
1858c2ecf20Sopenharmony_ci		return;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#ifdef SNDRV_LITTLE_ENDIAN
1888c2ecf20Sopenharmony_ci	if (parm_defs[type].type & PARM_IS_ALIGN_HI)
1898c2ecf20Sopenharmony_ci		offset++;
1908c2ecf20Sopenharmony_ci#else
1918c2ecf20Sopenharmony_ci	if (parm_defs[type].type & PARM_IS_ALIGN_LO)
1928c2ecf20Sopenharmony_ci		offset++;
1938c2ecf20Sopenharmony_ci#endif
1948c2ecf20Sopenharmony_ci	/* modify the register values */
1958c2ecf20Sopenharmony_ci	spin_lock_irqsave(&emu->voice_lock, flags);
1968c2ecf20Sopenharmony_ci	for (i = 0; i < emu->max_voices; i++) {
1978c2ecf20Sopenharmony_ci		struct snd_emux_voice *vp = &emu->voices[i];
1988c2ecf20Sopenharmony_ci		if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
1998c2ecf20Sopenharmony_ci			continue;
2008c2ecf20Sopenharmony_ci		srcp = (unsigned char*)&vp->reg.parm + offset;
2018c2ecf20Sopenharmony_ci		origp = (unsigned char*)&vp->zone->v.parm + offset;
2028c2ecf20Sopenharmony_ci		if (parm_defs[i].type & PARM_IS_BYTE) {
2038c2ecf20Sopenharmony_ci			*srcp = *origp;
2048c2ecf20Sopenharmony_ci			effect_set_byte(srcp, chan, type);
2058c2ecf20Sopenharmony_ci		} else {
2068c2ecf20Sopenharmony_ci			*(unsigned short*)srcp = *(unsigned short*)origp;
2078c2ecf20Sopenharmony_ci			effect_set_word((unsigned short*)srcp, chan, type);
2088c2ecf20Sopenharmony_ci		}
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&emu->voice_lock, flags);
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	/* activate them */
2138c2ecf20Sopenharmony_ci	snd_emux_update_channel(port, chan, parm_defs[type].update);
2148c2ecf20Sopenharmony_ci}
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci/* copy wavetable registers to voice table */
2188c2ecf20Sopenharmony_civoid
2198c2ecf20Sopenharmony_cisnd_emux_setup_effect(struct snd_emux_voice *vp)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	struct snd_midi_channel *chan = vp->chan;
2228c2ecf20Sopenharmony_ci	struct snd_emux_effect_table *fx;
2238c2ecf20Sopenharmony_ci	unsigned char *srcp;
2248c2ecf20Sopenharmony_ci	int i;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	if (! (fx = chan->private))
2278c2ecf20Sopenharmony_ci		return;
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	/* modify the register values via effect table */
2308c2ecf20Sopenharmony_ci	for (i = 0; i < EMUX_FX_END; i++) {
2318c2ecf20Sopenharmony_ci		int offset;
2328c2ecf20Sopenharmony_ci		if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
2338c2ecf20Sopenharmony_ci			continue;
2348c2ecf20Sopenharmony_ci#ifdef SNDRV_LITTLE_ENDIAN
2358c2ecf20Sopenharmony_ci		if (parm_defs[i].type & PARM_IS_ALIGN_HI)
2368c2ecf20Sopenharmony_ci			offset++;
2378c2ecf20Sopenharmony_ci#else
2388c2ecf20Sopenharmony_ci		if (parm_defs[i].type & PARM_IS_ALIGN_LO)
2398c2ecf20Sopenharmony_ci			offset++;
2408c2ecf20Sopenharmony_ci#endif
2418c2ecf20Sopenharmony_ci		srcp = (unsigned char*)&vp->reg.parm + offset;
2428c2ecf20Sopenharmony_ci		if (parm_defs[i].type & PARM_IS_BYTE)
2438c2ecf20Sopenharmony_ci			effect_set_byte(srcp, chan, i);
2448c2ecf20Sopenharmony_ci		else
2458c2ecf20Sopenharmony_ci			effect_set_word((unsigned short*)srcp, chan, i);
2468c2ecf20Sopenharmony_ci	}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	/* correct sample and loop points */
2498c2ecf20Sopenharmony_ci	vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
2508c2ecf20Sopenharmony_ci					   EMUX_FX_COARSE_SAMPLE_START,
2518c2ecf20Sopenharmony_ci					   vp->reg.sample_mode);
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
2548c2ecf20Sopenharmony_ci					       EMUX_FX_COARSE_LOOP_START,
2558c2ecf20Sopenharmony_ci					       vp->reg.sample_mode);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci	vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
2588c2ecf20Sopenharmony_ci					     EMUX_FX_COARSE_LOOP_END,
2598c2ecf20Sopenharmony_ci					     vp->reg.sample_mode);
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci/*
2638c2ecf20Sopenharmony_ci * effect table
2648c2ecf20Sopenharmony_ci */
2658c2ecf20Sopenharmony_civoid
2668c2ecf20Sopenharmony_cisnd_emux_create_effect(struct snd_emux_port *p)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	int i;
2698c2ecf20Sopenharmony_ci	p->effect = kcalloc(p->chset.max_channels,
2708c2ecf20Sopenharmony_ci			    sizeof(struct snd_emux_effect_table), GFP_KERNEL);
2718c2ecf20Sopenharmony_ci	if (p->effect) {
2728c2ecf20Sopenharmony_ci		for (i = 0; i < p->chset.max_channels; i++)
2738c2ecf20Sopenharmony_ci			p->chset.channels[i].private = p->effect + i;
2748c2ecf20Sopenharmony_ci	} else {
2758c2ecf20Sopenharmony_ci		for (i = 0; i < p->chset.max_channels; i++)
2768c2ecf20Sopenharmony_ci			p->chset.channels[i].private = NULL;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_civoid
2818c2ecf20Sopenharmony_cisnd_emux_delete_effect(struct snd_emux_port *p)
2828c2ecf20Sopenharmony_ci{
2838c2ecf20Sopenharmony_ci	kfree(p->effect);
2848c2ecf20Sopenharmony_ci	p->effect = NULL;
2858c2ecf20Sopenharmony_ci}
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_civoid
2888c2ecf20Sopenharmony_cisnd_emux_clear_effect(struct snd_emux_port *p)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	if (p->effect) {
2918c2ecf20Sopenharmony_ci		memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
2928c2ecf20Sopenharmony_ci		       p->chset.max_channels);
2938c2ecf20Sopenharmony_ci	}
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci#endif /* SNDRV_EMUX_USE_RAW_EFFECT */
297