DOSBox-X
|
00001 #include "np2glue.h" 00002 //#include "compiler.h" 00003 //#include "pccore.h" 00004 //#include "iocore.h" 00005 #include "sound.h" 00006 #include "fmboard.h" 00007 00008 00009 #define PCM86GET8(a) \ 00010 (a) = (SINT8)pcm86.buffer[pcm86.readpos & PCM86_BUFMSK] << 8; \ 00011 pcm86.readpos++; 00012 00013 #define PCM86GET16(a) \ 00014 (a) = (SINT8)pcm86.buffer[pcm86.readpos & PCM86_BUFMSK] << 8; \ 00015 pcm86.readpos++; \ 00016 (a) += pcm86.buffer[pcm86.readpos & PCM86_BUFMSK]; \ 00017 pcm86.readpos++; 00018 00019 #define BYVOLUME(s) ((((s) >> 6) * pcm86.volume) >> (PCM86_DIVBIT + 4)) 00020 00021 00022 static void pcm86mono16(SINT32 *pcm, UINT count) { 00023 00024 if (pcm86.div < PCM86_DIVENV) { // アップさんぷる 00025 do { 00026 SINT32 smp; 00027 if (pcm86.divremain < 0) { 00028 SINT32 dat; 00029 pcm86.divremain += PCM86_DIVENV; 00030 pcm86.realbuf -= 2; 00031 if (pcm86.realbuf < 0) { 00032 goto pm16_bufempty; 00033 } 00034 PCM86GET16(dat); 00035 pcm86.lastsmp = pcm86.smp; 00036 pcm86.smp = dat; 00037 } 00038 smp = (pcm86.lastsmp * pcm86.divremain) - 00039 (pcm86.smp * (pcm86.divremain - PCM86_DIVENV)); 00040 pcm[0] += BYVOLUME(smp); 00041 pcm += 2; 00042 pcm86.divremain -= pcm86.div; 00043 } while(--count); 00044 } 00045 else { 00046 do { 00047 SINT32 smp; 00048 smp = pcm86.smp * (pcm86.divremain * -1); 00049 pcm86.divremain += PCM86_DIVENV; 00050 while(1) { 00051 SINT32 dat; 00052 pcm86.realbuf -= 2; 00053 if (pcm86.realbuf < 0) { 00054 goto pm16_bufempty; 00055 } 00056 PCM86GET16(dat); 00057 pcm86.lastsmp = pcm86.smp; 00058 pcm86.smp = dat; 00059 if (pcm86.divremain > pcm86.div2) { 00060 pcm86.divremain -= pcm86.div2; 00061 smp += pcm86.smp * pcm86.div2; 00062 } 00063 else { 00064 break; 00065 } 00066 } 00067 smp += pcm86.smp * pcm86.divremain; 00068 pcm[0] += BYVOLUME(smp); 00069 pcm += 2; 00070 pcm86.divremain -= pcm86.div2; 00071 } while(--count); 00072 } 00073 return; 00074 00075 pm16_bufempty: 00076 pcm86.realbuf += 2; 00077 pcm86.divremain = 0; 00078 pcm86.smp = 0; 00079 pcm86.lastsmp = 0; 00080 } 00081 00082 static void pcm86stereo16(SINT32 *pcm, UINT count) { 00083 00084 if (pcm86.div < PCM86_DIVENV) { // アップさんぷる 00085 do { 00086 SINT32 smp; 00087 if (pcm86.divremain < 0) { 00088 SINT32 dat; 00089 pcm86.divremain += PCM86_DIVENV; 00090 pcm86.realbuf -= 4; 00091 if (pcm86.realbuf < 0) { 00092 goto ps16_bufempty; 00093 } 00094 PCM86GET16(dat); 00095 pcm86.lastsmp_l = pcm86.smp_l; 00096 pcm86.smp_l = dat; 00097 PCM86GET16(dat); 00098 pcm86.lastsmp_r = pcm86.smp_r; 00099 pcm86.smp_r = dat; 00100 } 00101 smp = (pcm86.lastsmp_l * pcm86.divremain) - 00102 (pcm86.smp_l * (pcm86.divremain - PCM86_DIVENV)); 00103 pcm[0] += BYVOLUME(smp); 00104 smp = (pcm86.lastsmp_r * pcm86.divremain) - 00105 (pcm86.smp_r * (pcm86.divremain - PCM86_DIVENV)); 00106 pcm[1] += BYVOLUME(smp); 00107 pcm += 2; 00108 pcm86.divremain -= pcm86.div; 00109 } while(--count); 00110 } 00111 else { 00112 do { 00113 SINT32 smp_l; 00114 SINT32 smp_r; 00115 smp_l = pcm86.smp_l * (pcm86.divremain * -1); 00116 smp_r = pcm86.smp_r * (pcm86.divremain * -1); 00117 pcm86.divremain += PCM86_DIVENV; 00118 while(1) { 00119 SINT32 dat; 00120 pcm86.realbuf -= 4; 00121 if (pcm86.realbuf < 4) { 00122 goto ps16_bufempty; 00123 } 00124 PCM86GET16(dat); 00125 pcm86.lastsmp_l = pcm86.smp_l; 00126 pcm86.smp_l = dat; 00127 PCM86GET16(dat); 00128 pcm86.lastsmp_r = pcm86.smp_r; 00129 pcm86.smp_r = dat; 00130 if (pcm86.divremain > pcm86.div2) { 00131 pcm86.divremain -= pcm86.div2; 00132 smp_l += pcm86.smp_l * pcm86.div2; 00133 smp_r += pcm86.smp_r * pcm86.div2; 00134 } 00135 else { 00136 break; 00137 } 00138 } 00139 smp_l += pcm86.smp_l * pcm86.divremain; 00140 smp_r += pcm86.smp_r * pcm86.divremain; 00141 pcm[0] += BYVOLUME(smp_l); 00142 pcm[1] += BYVOLUME(smp_r); 00143 pcm += 2; 00144 pcm86.divremain -= pcm86.div2; 00145 } while(--count); 00146 } 00147 return; 00148 00149 ps16_bufempty: 00150 pcm86.realbuf += 4; 00151 pcm86.divremain = 0; 00152 pcm86.smp_l = 0; 00153 pcm86.smp_r = 0; 00154 pcm86.lastsmp_l = 0; 00155 pcm86.lastsmp_r = 0; 00156 } 00157 00158 static void pcm86mono8(SINT32 *pcm, UINT count) { 00159 00160 if (pcm86.div < PCM86_DIVENV) { // アップさんぷる 00161 do { 00162 SINT32 smp; 00163 if (pcm86.divremain < 0) { 00164 SINT32 dat; 00165 pcm86.divremain += PCM86_DIVENV; 00166 pcm86.realbuf--; 00167 if (pcm86.realbuf < 0) { 00168 goto pm8_bufempty; 00169 } 00170 PCM86GET8(dat); 00171 pcm86.lastsmp = pcm86.smp; 00172 pcm86.smp = dat; 00173 } 00174 smp = (pcm86.lastsmp * pcm86.divremain) - 00175 (pcm86.smp * (pcm86.divremain - PCM86_DIVENV)); 00176 pcm[0] += BYVOLUME(smp); 00177 pcm += 2; 00178 pcm86.divremain -= pcm86.div; 00179 } while(--count); 00180 } 00181 else { 00182 do { 00183 SINT32 smp; 00184 smp = pcm86.smp * (pcm86.divremain * -1); 00185 pcm86.divremain += PCM86_DIVENV; 00186 while(1) { 00187 SINT32 dat; 00188 pcm86.realbuf--; 00189 if (pcm86.realbuf < 0) { 00190 goto pm8_bufempty; 00191 } 00192 PCM86GET8(dat); 00193 pcm86.lastsmp = pcm86.smp; 00194 pcm86.smp = dat; 00195 if (pcm86.divremain > pcm86.div2) { 00196 pcm86.divremain -= pcm86.div2; 00197 smp += pcm86.smp * pcm86.div2; 00198 } 00199 else { 00200 break; 00201 } 00202 } 00203 smp += pcm86.smp * pcm86.divremain; 00204 pcm[0] += BYVOLUME(smp); 00205 pcm += 2; 00206 pcm86.divremain -= pcm86.div2; 00207 } while(--count); 00208 } 00209 return; 00210 00211 pm8_bufempty: 00212 pcm86.realbuf += 1; 00213 pcm86.divremain = 0; 00214 pcm86.smp = 0; 00215 pcm86.lastsmp = 0; 00216 } 00217 00218 static void pcm86stereo8(SINT32 *pcm, UINT count) { 00219 00220 if (pcm86.div < PCM86_DIVENV) { // アップさんぷる 00221 do { 00222 SINT32 smp; 00223 if (pcm86.divremain < 0) { 00224 SINT32 dat; 00225 pcm86.divremain += PCM86_DIVENV; 00226 pcm86.realbuf -= 2; 00227 if (pcm86.realbuf < 0) { 00228 goto pm8_bufempty; 00229 } 00230 PCM86GET8(dat); 00231 pcm86.lastsmp_l = pcm86.smp_l; 00232 pcm86.smp_l = dat; 00233 PCM86GET8(dat); 00234 pcm86.lastsmp_r = pcm86.smp_r; 00235 pcm86.smp_r = dat; 00236 } 00237 smp = (pcm86.lastsmp_l * pcm86.divremain) - 00238 (pcm86.smp_l * (pcm86.divremain - PCM86_DIVENV)); 00239 pcm[0] += BYVOLUME(smp); 00240 smp = (pcm86.lastsmp_r * pcm86.divremain) - 00241 (pcm86.smp_r * (pcm86.divremain - PCM86_DIVENV)); 00242 pcm[1] += BYVOLUME(smp); 00243 pcm += 2; 00244 pcm86.divremain -= pcm86.div; 00245 } while(--count); 00246 } 00247 else { 00248 do { 00249 SINT32 smp_l; 00250 SINT32 smp_r; 00251 smp_l = pcm86.smp_l * (pcm86.divremain * -1); 00252 smp_r = pcm86.smp_r * (pcm86.divremain * -1); 00253 pcm86.divremain += PCM86_DIVENV; 00254 while(1) { 00255 SINT32 dat; 00256 pcm86.realbuf -= 2; 00257 if (pcm86.realbuf < 0) { 00258 goto pm8_bufempty; 00259 } 00260 PCM86GET8(dat); 00261 pcm86.lastsmp_l = pcm86.smp_l; 00262 pcm86.smp_l = dat; 00263 PCM86GET8(dat); 00264 pcm86.lastsmp_r = pcm86.smp_r; 00265 pcm86.smp_r = dat; 00266 if (pcm86.divremain > pcm86.div2) { 00267 pcm86.divremain -= pcm86.div2; 00268 smp_l += pcm86.smp_l * pcm86.div2; 00269 smp_r += pcm86.smp_r * pcm86.div2; 00270 } 00271 else { 00272 break; 00273 } 00274 } 00275 smp_l += pcm86.smp_l * pcm86.divremain; 00276 smp_r += pcm86.smp_r * pcm86.divremain; 00277 pcm[0] += BYVOLUME(smp_l); 00278 pcm[1] += BYVOLUME(smp_r); 00279 pcm += 2; 00280 pcm86.divremain -= pcm86.div2; 00281 } while(--count); 00282 } 00283 return; 00284 00285 pm8_bufempty: 00286 pcm86.realbuf += 2; 00287 pcm86.divremain = 0; 00288 pcm86.smp_l = 0; 00289 pcm86.smp_r = 0; 00290 pcm86.lastsmp_l = 0; 00291 pcm86.lastsmp_r = 0; 00292 } 00293 00294 void SOUNDCALL pcm86gen_getpcm(void *hdl, SINT32 *pcm, UINT count) { 00295 00296 if ((count) && (pcm86.fifo & 0x80) && (pcm86.div)) { 00297 switch(pcm86.dactrl & 0x70) { 00298 case 0x00: // 16bit-none 00299 break; 00300 00301 case 0x10: // 16bit-right 00302 pcm86mono16(pcm + 1, count); 00303 break; 00304 00305 case 0x20: // 16bit-left 00306 pcm86mono16(pcm, count); 00307 break; 00308 00309 case 0x30: // 16bit-stereo 00310 pcm86stereo16(pcm, count); 00311 break; 00312 00313 case 0x40: // 8bit-none 00314 break; 00315 00316 case 0x50: // 8bit-right 00317 pcm86mono8(pcm + 1, count); 00318 break; 00319 00320 case 0x60: // 8bit-left 00321 pcm86mono8(pcm, count); 00322 break; 00323 00324 case 0x70: // 8bit-stereo 00325 pcm86stereo8(pcm, count); 00326 break; 00327 } 00328 pcm86gen_checkbuf(); 00329 } 00330 (void)hdl; 00331 } 00332