Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Jaroslav Kysela | 686 | 85.22% | 3 | 15.79% |
Takashi Iwai | 91 | 11.30% | 3 | 15.79% |
Linus Torvalds (pre-git) | 17 | 2.11% | 9 | 47.37% |
Gustavo A. R. Silva | 4 | 0.50% | 1 | 5.26% |
Pierre-Louis Bossart | 4 | 0.50% | 1 | 5.26% |
Thomas Gleixner | 2 | 0.25% | 1 | 5.26% |
Masanari Iida | 1 | 0.12% | 1 | 5.26% |
Total | 805 | 19 |
// 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. */ #include "emu10k1_synth_local.h" /* */ #define BLANK_LOOP_START 4 #define BLANK_LOOP_END 8 #define BLANK_LOOP_SIZE 12 #define BLANK_HEAD_SIZE 32 /* * 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, const void __user *data, long count) { int offset; int truesize, size, blocksize; __maybe_unused int loopsize; int loopend, sampleend; unsigned int start_addr; struct snd_emu10k1 *emu; emu = rec->hw; if (snd_BUG_ON(!sp || !hdr)) return -EINVAL; if (sp->v.size == 0) { dev_dbg(emu->card->dev, "emu: rom font for sample %d\n", sp->v.sample); return 0; } /* recalculate address offset */ sp->v.end -= sp->v.start; sp->v.loopstart -= sp->v.start; sp->v.loopend -= sp->v.start; sp->v.start = 0; /* some samples have invalid data. the addresses are corrected in voice info */ sampleend = sp->v.end; if (sampleend > sp->v.size) sampleend = sp->v.size; loopend = sp->v.loopend; if (loopend > sampleend) loopend = sampleend; /* be sure loop points start < end */ if (sp->v.loopstart >= sp->v.loopend) swap(sp->v.loopstart, sp->v.loopend); /* compute true data size to be loaded */ truesize = sp->v.size + BLANK_HEAD_SIZE; loopsize = 0; #if 0 /* not supported */ if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) loopsize = sp->v.loopend - sp->v.loopstart; truesize += loopsize; #endif if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) truesize += BLANK_LOOP_SIZE; /* try to allocate a memory block */ blocksize = truesize; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) blocksize *= 2; 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; /* write blank samples at head */ offset = 0; size = BLANK_HEAD_SIZE; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; if (offset + size > blocksize) return -EINVAL; snd_emu10k1_synth_bzero(emu, sp->block, offset, size); offset += size; /* copy start->loopend */ size = loopend; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; if (offset + size > blocksize) return -EINVAL; if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { snd_emu10k1_synth_free(emu, sp->block); sp->block = NULL; return -EFAULT; } offset += size; data += size; #if 0 /* not supported yet */ /* handle reverse (or bidirectional) loop */ if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) { /* copy loop in reverse */ if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) { int woffset; unsigned short *wblock = (unsigned short*)block; woffset = offset / 2; if (offset + loopsize * 2 > blocksize) return -EINVAL; for (i = 0; i < loopsize; i++) wblock[woffset + i] = wblock[woffset - i -1]; offset += loopsize * 2; } else { if (offset + loopsize > blocksize) return -EINVAL; for (i = 0; i < loopsize; i++) block[offset + i] = block[offset - i -1]; offset += loopsize; } /* modify loop pointers */ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) { sp->v.loopend += loopsize; } else { sp->v.loopstart += loopsize; sp->v.loopend += loopsize; } /* add sample pointer */ sp->v.end += loopsize; } #endif /* loopend -> sample end */ size = sp->v.size - loopend; if (size < 0) return -EINVAL; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { snd_emu10k1_synth_free(emu, sp->block); sp->block = NULL; return -EFAULT; } offset += size; /* clear rest of samples (if any) */ if (offset < blocksize) snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset); if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) { /* 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; } } #if 0 /* not supported yet */ if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) { /* unsigned -> signed */ if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) { unsigned short *wblock = (unsigned short*)block; for (i = 0; i < truesize; i++) wblock[i] ^= 0x8000; } else { for (i = 0; i < truesize; i++) block[i] ^= 0x80; } } #endif /* recalculate offset */ start_addr = BLANK_HEAD_SIZE * 2; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) start_addr >>= 1; sp->v.start += start_addr; sp->v.end += start_addr; sp->v.loopstart += start_addr; sp->v.loopend += start_addr; return 0; } /* * free a sample block */ int snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp, struct snd_util_memhdr *hdr) { struct snd_emu10k1 *emu; emu = rec->hw; if (snd_BUG_ON(!sp || !hdr)) return -EINVAL; if (sp->block) { snd_emu10k1_synth_free(emu, sp->block); sp->block = NULL; } return 0; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1