linux/sound/isa/sb/emu8000_pcm.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * pcm emulation on emu8000 wavetable
 *
 *  Copyright (C) 2002 Takashi Iwai <[email protected]>
 */

#include "emu8000_local.h"

#include <linux/sched/signal.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/pcm.h>

/*
 * define the following if you want to use this pcm with non-interleaved mode
 */
/* #define USE_NONINTERLEAVE */

/* NOTE: for using the non-interleaved mode with alsa-lib, you have to set
 * mmap_emulation flag to 1 in your .asoundrc, such like
 *
 *	pcm.emu8k {
 *		type plug
 *		slave.pcm {
 *			type hw
 *			card 0
 *			device 1
 *			mmap_emulation 1
 *		}
 *	}
 *
 * besides, for the time being, the non-interleaved mode doesn't work well on
 * alsa-lib...
 */


struct snd_emu8k_pcm {};

#define LOOP_BLANK_SIZE


/*
 * open up channels for the simultaneous data transfer and playback
 */
static int
emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels)
{}

/*
 */
static void
snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule)
{}

/*
 * close all channels
 */
static void
emu8k_close_dram(struct snd_emu8000 *emu)
{}

/*
 * convert Hz to AWE32 rate offset (see emux/soundfont.c)
 */

#define OFFSET_SAMPLERATE
#define SAMPLERATE_RATIO

static int calc_rate_offset(int hz)
{}


/*
 */

static const struct snd_pcm_hardware emu8k_pcm_hw =;

/*
 * get the current position at the given channel from CCCA register
 */
static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
{}


/*
 * timer interrupt handler
 * check the current position and update the period if necessary.
 */
static void emu8k_pcm_timer_func(struct timer_list *t)
{}


/*
 * open pcm
 * creating an instance here
 */
static int emu8k_pcm_open(struct snd_pcm_substream *subs)
{}

static int emu8k_pcm_close(struct snd_pcm_substream *subs)
{}

/*
 * calculate pitch target
 */
static int calc_pitch_target(int pitch)
{}

/*
 * set up the voice
 */
static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
{}

/*
 * trigger the voice
 */
static void start_voice(struct snd_emu8k_pcm *rec, int ch)
{}

/*
 * stop the voice immediately
 */
static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
{}

static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
{}


/*
 * copy / silence ops
 */

/*
 * this macro should be inserted in the copy/silence loops
 * to reduce the latency.  without this, the system will hang up
 * during the whole loop.
 */
#define CHECK_SCHEDULER()

#define GET_VAL(sval, iter)

#ifdef USE_NONINTERLEAVE

#define LOOP_WRITE

/* copy one channel block */
static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
			  int voice, unsigned long pos,
			  struct iov_iter *src, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to word unit */
	pos = (pos << 1) + rec->loop_start[voice];
	count <<= 1;
	LOOP_WRITE(rec, pos, src, count);
	return 0;
}

/* make a channel block silence */
static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
			     int voice, unsigned long pos, unsigned long count)
{
	struct snd_emu8k_pcm *rec = subs->runtime->private_data;

	/* convert to word unit */
	pos = (pos << 1) + rec->loop_start[voice];
	count <<= 1;
	LOOP_WRITE(rec, pos, NULL, count);
	return 0;
}

#else /* interleave */

#define LOOP_WRITE(rec, pos, iter, count)


/*
 * copy the interleaved data can be done easily by using
 * DMA "left" and "right" channels on emu8k engine.
 */
static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
			  int voice, unsigned long pos,
			  struct iov_iter *src, unsigned long count)
{}

static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
			     int voice, unsigned long pos, unsigned long count)
{}
#endif


/*
 * allocate a memory block
 */
static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs,
			       struct snd_pcm_hw_params *hw_params)
{}

/*
 * free the memory block
 */
static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs)
{}

/*
 */
static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
{}

static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
{}


static const struct snd_pcm_ops emu8k_pcm_ops =;


static void snd_emu8000_pcm_free(struct snd_pcm *pcm)
{}

int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index)
{}