23 #include <linux/slab.h>
72 #define LOOP_BLANK_SIZE 8
92 #ifndef USE_NONINTERLEAVE
93 if (channels > 1 && (i & 1) != 0)
134 for (i = 0; i < 2; i++)
146 #define OFFSET_SAMPLERATE 1011119
147 #define SAMPLERATE_RATIO 4096
149 static int calc_rate_offset(
int hz)
159 #ifdef USE_NONINTERLEAVE
170 .buffer_bytes_max = (128*1024),
182 static inline int emu8k_get_curpos(
struct snd_emu8k_pcm *rec,
int ch)
194 static void emu8k_pcm_timer_func(
unsigned long data)
201 ptr = emu8k_get_curpos(rec, 0);
244 rec->
timer.function = emu8k_pcm_timer_func;
247 runtime->
hw = emu8k_pcm_hw;
249 runtime->
hw.period_bytes_max = runtime->
hw.buffer_bytes_max / 2;
269 static int calc_pitch_target(
int pitch)
271 int ptarget = 1 << (pitch >> 12);
272 if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710;
273 if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710;
274 if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710;
275 ptarget += (ptarget >> 1);
276 if (ptarget > 0xffff) ptarget = 0xffff;
318 temp = (temp <<24) | ((
unsigned int)rec->
loop_start[ch] - 1);
326 temp = (temp << 28) | ((
unsigned int)rec->
loop_start[ch] - 1);
341 int pt = calc_pitch_target(rec->
pitch);
354 aux = (-rec->
panning[ch]) & 0xff;
355 temp = (temp << 8) | (pt << 16) |
aux;
366 spin_unlock_irqrestore(&rec->
timer_lock, flags);
385 spin_unlock_irqrestore(&rec->
timer_lock, flags);
395 for (ch = 0; ch < rec->
voices; ch++)
396 start_voice(rec, ch);
401 for (ch = 0; ch < rec->
voices; ch++)
420 #define CHECK_SCHEDULER() \
423 if (signal_pending(current))\
428 #ifdef USE_NONINTERLEAVE
454 snd_emu8000_write_wait(emu, 1);
456 unsigned short *
buf =
src;
459 for (i = 0; i < rec->
voices; i++) {
460 err = emu8k_transfer_block(emu, pos + rec->
loop_start[i], buf, count);
467 return emu8k_transfer_block(emu, pos + rec->
loop_start[voice], src, count);
491 snd_emu8000_write_wait(emu, 1);
492 if (voice == -1 && rec->
voices == 1)
496 err = emu8k_silence_block(emu, pos + rec->
loop_start[0], count / 2);
499 return emu8k_silence_block(emu, pos + rec->
loop_start[1], count / 2);
501 return emu8k_silence_block(emu, pos + rec->
loop_start[voice], count);
521 snd_emu8000_write_wait(emu, 1);
526 while (count-- > 0) {
552 snd_emu8000_write_wait(emu, 1);
556 while (count-- > 0) {
603 for (ch = 0; ch < rec->
voices; ch++)
606 emu8k_close_dram(rec->
emu);
619 rec->
pitch = 0xe000 + calc_rate_offset(subs->
runtime->rate);
639 if ((err = emu8k_open_dram_for_pcm(rec->
emu, rec->
voices)) != 0)
644 snd_emu8000_write_wait(rec->
emu, 0);
648 for (ch = 0; ch < rec->
voices; ch++) {
665 return emu8k_get_curpos(rec, 0);
671 .open = emu8k_pcm_open,
672 .close = emu8k_pcm_close,
674 .hw_params = emu8k_pcm_hw_params,
675 .hw_free = emu8k_pcm_hw_free,
676 .prepare = emu8k_pcm_prepare,
677 .trigger = emu8k_pcm_trigger,
678 .pointer = emu8k_pcm_pointer,
679 .copy = emu8k_pcm_copy,
680 .silence = emu8k_pcm_silence,
684 static void snd_emu8000_pcm_free(
struct snd_pcm *pcm)
695 if ((err =
snd_pcm_new(card,
"Emu8000 PCM", index, 1, 0, &pcm)) < 0)