PCem

view src/sound.c @ 113:f749363ad763

Added per-device configuration. Reworked configuration parser a bit. Added configuration for S3 ViRGE and 8-bit Sound Blasters. IRQ 2 routed to IRQ 9 on AT machines.
author TomW
date Mon Jun 30 21:31:28 2014 +0100
parents df66658b3f06
children a6ce8addfffa
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "ibm.h"
4 #include "device.h"
6 #include "filters.h"
8 #include "sound_opl.h"
10 #include "sound.h"
11 #include "sound_adlib.h"
12 #include "sound_adlibgold.h"
13 #include "sound_pas16.h"
14 #include "sound_sb.h"
15 #include "sound_sb_dsp.h"
16 #include "sound_wss.h"
18 #include "timer.h"
20 int sound_card_current = 0;
21 static int sound_card_last = 0;
23 typedef struct
24 {
25 char name[32];
26 device_t *device;
27 } SOUND_CARD;
29 static SOUND_CARD sound_cards[] =
30 {
31 {"None", NULL},
32 {"Adlib", &adlib_device},
33 {"Sound Blaster 1.0", &sb_1_device},
34 {"Sound Blaster 1.5", &sb_15_device},
35 {"Sound Blaster 2.0", &sb_2_device},
36 {"Sound Blaster Pro v1", &sb_pro_v1_device},
37 {"Sound Blaster Pro v2", &sb_pro_v2_device},
38 {"Sound Blaster 16", &sb_16_device},
39 {"Sound Blaster AWE32", &sb_awe32_device},
40 {"Adlib Gold", &adgold_device},
41 {"Windows Sound System", &wss_device},
42 {"Pro Audio Spectrum 16", &pas16_device},
43 {"", NULL}
44 };
46 int sound_card_available(int card)
47 {
48 if (sound_cards[card].device)
49 return device_available(sound_cards[card].device);
51 return 1;
52 }
54 char *sound_card_getname(int card)
55 {
56 return sound_cards[card].name;
57 }
59 device_t *sound_card_getdevice(int card)
60 {
61 return sound_cards[card].device;
62 }
64 int sound_card_has_config(int card)
65 {
66 return sound_cards[card].device->config ? 1 : 0;
67 }
69 void sound_card_init()
70 {
71 if (sound_cards[sound_card_current].device)
72 device_add(sound_cards[sound_card_current].device);
73 sound_card_last = sound_card_current;
74 }
76 static struct
77 {
78 void (*poll)(void *p);
79 void (*get_buffer)(int16_t *buffer, int len, void *p);
80 void *priv;
81 } sound_handlers[8];
83 static int sound_handlers_num;
85 static int sound_poll_time = 0, sound_get_buffer_time = 0;
87 int soundon = 1;
90 static int16_t cd_buffer[SOUNDBUFLEN * 2];
92 void sound_cd_poll(void *p)
93 {
94 }
96 void sound_cd_get_buffer(int16_t *buffer, int len, void *p)
97 {
98 int pos, c;
99 ioctl_audio_callback(cd_buffer, (len * 2 * 441) / 480);
100 pos = 0;
102 for (c = 0; c < len * 2; c+=2)
103 {
104 buffer[c] += cd_buffer[((pos >> 16) << 1)] / 2;
105 buffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2;
106 pos += 60211; //(44100 * 65536) / 48000;
107 }
108 }
110 static uint16_t *outbuffer;
112 void sound_init()
113 {
114 initalmain(0,NULL);
115 inital();
117 outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t));
119 sound_add_handler(sound_cd_poll, sound_cd_get_buffer, NULL);
120 }
122 void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p)
123 {
124 sound_handlers[sound_handlers_num].poll = poll;
125 sound_handlers[sound_handlers_num].get_buffer = get_buffer;
126 sound_handlers[sound_handlers_num].priv = p;
127 sound_handlers_num++;
128 }
130 void sound_poll(void *priv)
131 {
132 int c;
134 sound_poll_time += (int)((double)TIMER_USEC * (1000000.0 / 48000.0));
136 for (c = 0; c < sound_handlers_num; c++)
137 sound_handlers[c].poll(sound_handlers[c].priv);
138 }
140 FILE *soundf;
142 void sound_get_buffer(void *priv)
143 {
144 int c;
146 sound_get_buffer_time += (TIMER_USEC * (1000000 / 10));
148 memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int16_t));
150 for (c = 0; c < sound_handlers_num; c++)
151 sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv);
153 /* if (!soundf) soundf=fopen("sound.pcm","wb");
154 fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf);*/
156 if (soundon) givealbuffer(outbuffer);
157 }
159 void sound_reset()
160 {
161 timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL);
162 timer_add(sound_get_buffer, &sound_get_buffer_time, TIMER_ALWAYS_ENABLED, NULL);
164 sound_handlers_num = 0;
165 }