// SPDX-License-Identifier: GPL-2.0-or-later /* * Patch transfer callback for Emu10k1 * * Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
*/ /* * All the code for loading in a patch. There is very little that is * chip specific here. Just the actual writing to the board.
*/
/* * allocate a sample block and copy data from userspace
*/ int
snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, struct snd_util_memhdr *hdr, constvoid __user *data, long count)
{
u8 fill;
u32 xor; int shift; int offset; int truesize, size, blocksize; int loop_start, loop_end, loop_size, data_end, unroll; struct snd_emu10k1 *emu;
emu = rec->hw; if (snd_BUG_ON(!sp || !hdr)) return -EINVAL;
if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP | SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) { /* should instead return -ENOTSUPP; but compatibility */
dev_warn(emu->card->dev, "Emu10k1 wavetable patch %d with unsupported loop feature\n",
sp->v.sample);
}
/* compute true data size to be loaded */
truesize = sp->v.size + BLANK_HEAD_SIZE; if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
truesize += BLANK_LOOP_SIZE; /* if no blank loop is attached in the sample, add it */ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
sp->v.loopend = sp->v.end + BLANK_LOOP_END;
}
}
// Automatic pre-filling of the cache does not work in the presence // of loops (*), and we don't want to fill it manually, as that is // fiddly and slow. So we unroll the loop until the loop end is // beyond the cache size. // (*) Strictly speaking, a single iteration is supported (that's // how it works when the playback engine runs), but handling this // special case is not worth it.
unroll = 0; while (sp->v.loopend < 64) {
truesize += loop_size;
sp->v.loopstart += loop_size;
sp->v.loopend += loop_size;
sp->v.end += loop_size;
unroll++;
}
/* try to allocate a memory block */
blocksize = truesize << shift;
sp->block = snd_emu10k1_synth_alloc(emu, blocksize); if (sp->block == NULL) {
dev_dbg(emu->card->dev, "synth malloc failed (size=%d)\n", blocksize); /* not ENOMEM (for compatibility with OSS) */ return -ENOSPC;
} /* set the total size */
sp->v.truesize = blocksize;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.