gus_sample.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Routines for Gravis UltraSound soundcards - Sample support
  3. * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  4. *
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. */
  21. #include <sound/driver.h>
  22. #include <linux/time.h>
  23. #include <sound/core.h>
  24. #include <sound/gus.h>
  25. /*
  26. *
  27. */
  28. static void select_instrument(struct snd_gus_card * gus, struct snd_gus_voice * v)
  29. {
  30. struct snd_seq_kinstr *instr;
  31. #if 0
  32. printk("select instrument: cluster = %li, std = 0x%x, bank = %i, prg = %i\n",
  33. v->instr.cluster,
  34. v->instr.std,
  35. v->instr.bank,
  36. v->instr.prg);
  37. #endif
  38. instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1);
  39. if (instr != NULL) {
  40. if (instr->ops) {
  41. if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
  42. snd_gf1_simple_init(v);
  43. }
  44. snd_seq_instr_free_use(gus->gf1.ilist, instr);
  45. }
  46. }
  47. /*
  48. *
  49. */
  50. static void event_sample(struct snd_seq_event *ev, struct snd_gus_port *p,
  51. struct snd_gus_voice *v)
  52. {
  53. if (v->sample_ops && v->sample_ops->sample_stop)
  54. v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY);
  55. v->instr.std = ev->data.sample.param.sample.std;
  56. if (v->instr.std & 0xff000000) { /* private instrument */
  57. v->instr.std &= 0x00ffffff;
  58. v->instr.std |= (unsigned int)ev->source.client << 24;
  59. }
  60. v->instr.bank = ev->data.sample.param.sample.bank;
  61. v->instr.prg = ev->data.sample.param.sample.prg;
  62. select_instrument(p->gus, v);
  63. }
  64. static void event_cluster(struct snd_seq_event *ev, struct snd_gus_port *p,
  65. struct snd_gus_voice *v)
  66. {
  67. if (v->sample_ops && v->sample_ops->sample_stop)
  68. v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY);
  69. v->instr.cluster = ev->data.sample.param.cluster.cluster;
  70. select_instrument(p->gus, v);
  71. }
  72. static void event_start(struct snd_seq_event *ev, struct snd_gus_port *p,
  73. struct snd_gus_voice *v)
  74. {
  75. if (v->sample_ops && v->sample_ops->sample_start)
  76. v->sample_ops->sample_start(p->gus, v, ev->data.sample.param.position);
  77. }
  78. static void event_stop(struct snd_seq_event *ev, struct snd_gus_port *p,
  79. struct snd_gus_voice *v)
  80. {
  81. if (v->sample_ops && v->sample_ops->sample_stop)
  82. v->sample_ops->sample_stop(p->gus, v, ev->data.sample.param.stop_mode);
  83. }
  84. static void event_freq(struct snd_seq_event *ev, struct snd_gus_port *p,
  85. struct snd_gus_voice *v)
  86. {
  87. if (v->sample_ops && v->sample_ops->sample_freq)
  88. v->sample_ops->sample_freq(p->gus, v, ev->data.sample.param.frequency);
  89. }
  90. static void event_volume(struct snd_seq_event *ev, struct snd_gus_port *p,
  91. struct snd_gus_voice *v)
  92. {
  93. if (v->sample_ops && v->sample_ops->sample_volume)
  94. v->sample_ops->sample_volume(p->gus, v, &ev->data.sample.param.volume);
  95. }
  96. static void event_loop(struct snd_seq_event *ev, struct snd_gus_port *p,
  97. struct snd_gus_voice *v)
  98. {
  99. if (v->sample_ops && v->sample_ops->sample_loop)
  100. v->sample_ops->sample_loop(p->gus, v, &ev->data.sample.param.loop);
  101. }
  102. static void event_position(struct snd_seq_event *ev, struct snd_gus_port *p,
  103. struct snd_gus_voice *v)
  104. {
  105. if (v->sample_ops && v->sample_ops->sample_pos)
  106. v->sample_ops->sample_pos(p->gus, v, ev->data.sample.param.position);
  107. }
  108. static void event_private1(struct snd_seq_event *ev, struct snd_gus_port *p,
  109. struct snd_gus_voice *v)
  110. {
  111. if (v->sample_ops && v->sample_ops->sample_private1)
  112. v->sample_ops->sample_private1(p->gus, v, (unsigned char *)&ev->data.sample.param.raw8);
  113. }
  114. typedef void (gus_sample_event_handler_t)(struct snd_seq_event *ev,
  115. struct snd_gus_port *p,
  116. struct snd_gus_voice *v);
  117. static gus_sample_event_handler_t *gus_sample_event_handlers[9] = {
  118. event_sample,
  119. event_cluster,
  120. event_start,
  121. event_stop,
  122. event_freq,
  123. event_volume,
  124. event_loop,
  125. event_position,
  126. event_private1
  127. };
  128. void snd_gus_sample_event(struct snd_seq_event *ev, struct snd_gus_port *p)
  129. {
  130. int idx, voice;
  131. struct snd_gus_card *gus = p->gus;
  132. struct snd_gus_voice *v;
  133. unsigned long flags;
  134. idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE;
  135. if (idx < 0 || idx > 8)
  136. return;
  137. for (voice = 0; voice < 32; voice++) {
  138. v = &gus->gf1.voices[voice];
  139. if (v->use && v->client == ev->source.client &&
  140. v->port == ev->source.port &&
  141. v->index == ev->data.sample.channel) {
  142. spin_lock_irqsave(&gus->event_lock, flags);
  143. gus_sample_event_handlers[idx](ev, p, v);
  144. spin_unlock_irqrestore(&gus->event_lock, flags);
  145. return;
  146. }
  147. }
  148. }