s_sound.c (6992B)
1 /* s_sound.c */ 2 #include "doomdef.h" 3 #include "p_local.h" 4 #include "r_local.h" 5 6 #define AUDIO_HEAP_SIZE (0x44800) 7 extern u64 audio_heap[AUDIO_HEAP_SIZE / sizeof(u64)];//80325800 8 9 extern char _doom64_wmdSegmentRomStart[], _doom64_wmdSegmentRomEnd[]; 10 extern char _doom64_wsdSegmentRomStart[], _doom64_wsdSegmentRomEnd[]; 11 extern char _doom64_wddSegmentRomStart[], _doom64_wddSegmentRomEnd[]; 12 13 #define SYS_FRAMES_PER_SEC 30 14 15 void S_Error_Callback_Routine(char *errstring, int errnum1, int errnum2) // 80029580 16 { 17 I_Error(errstring, errnum1, errnum2); 18 } 19 20 extern int SfxVolume; 21 extern int MusVolume; 22 23 extern void wess_set_tweaks2(WessTweakAttr *attr); 24 extern void wess_get_tweaks2(WessTweakAttr *attr); 25 26 void S_Init(void) // 80029590 27 { 28 int audioHeapEnd; 29 int wmdlength; 30 int loaded; 31 int modulesize; 32 int seqsize, seqtblsize; 33 char *moduleptr; 34 char *seqptr, *seqtblptr; 35 u32 old_ovmemptr; 36 void *tempram; 37 38 WessTweakAttr tweak; 39 WessConfig wess_config; 40 ALHeap sys_aheap; 41 42 //PRINTF_D(WHITE, "S_Init: Start"); 43 44 alHeapInit(&sys_aheap, (u8 *)audio_heap, AUDIO_HEAP_SIZE); 45 46 //PRINTF_D(WHITE, "base %x", (int)&sys_aheap.base); 47 //PRINTF_D(WHITE, "cur %x", (int)&sys_aheap.cur); 48 //PRINTF_D(WHITE, "len %d", sys_aheap.len); 49 //PRINTF_D(WHITE, "count %d", sys_aheap.count); 50 51 wess_set_error_callback(S_Error_Callback_Routine); 52 53 /* tweak audio */ 54 wess_get_tweaks(&tweak); 55 56 tweak.mask = TWEAK_DMA_BUFFERS | TWEAK_DMA_MESSAGES | TWEAK_DMA_BUFFER_LENGTH; 57 tweak.dma_buffers = 40; 58 tweak.dma_messages = 56; 59 tweak.dma_buffer_length = 0x600; 60 wess_set_tweaks(&tweak); 61 62 /* init audio */ 63 wess_config.heap_ptr = &sys_aheap; 64 wess_config.outputsamplerate = 22050; 65 wess_config.maxACMDSize = 1024 * 3; 66 wess_config.wdd_location = _doom64_wddSegmentRomStart; 67 wess_config.reverb_id = WESS_REVERB_BIGROOM; 68 wess_config.revtbl_ptr = 0; 69 wess_config.audioframerate = (f32)SYS_FRAMES_PER_SEC; 70 71 wess_init(&wess_config); 72 73 //PRINTF_D(WHITE, "heap_ptr %x", (int)&wess_config.heap_ptr); 74 //PRINTF_D(WHITE, "outputsamplerate %d", wess_config.outputsamplerate); 75 //PRINTF_D(WHITE, "maxACMDSize %d", wess_config.maxACMDSize); 76 //PRINTF_D(WHITE, "wdd_location %x", (int)&wess_config.wdd_location); 77 //PRINTF_D(WHITE, "reverb_id %d", wess_config.reverb_id); 78 //PRINTF_D(WHITE, "revtbl_ptr %d", wess_config.revtbl_ptr); 79 //PRINTF_D(WHITE, "audioframerate %f", (f32)wess_config.audioframerate); 80 81 // now we load the .wmd image into a temporary ram space 82 modulesize = wess_size_module(_doom64_wmdSegmentRomStart); 83 modulesize = (modulesize + 15 & ~15); 84 moduleptr = alHeapAlloc(&sys_aheap, 1, modulesize); 85 //PRINTF_D(WHITE, "modulesize %d", modulesize); 86 //PRINTF_D(WHITE, "moduleptr %x", (int)&moduleptr); 87 88 loaded = wess_load_module(_doom64_wmdSegmentRomStart, moduleptr, modulesize); 89 //PRINTF_D(WHITE, "loaded %d", loaded); 90 91 92 seqtblsize = wess_seq_loader_sizeof(wess_get_master_status(), _doom64_wsdSegmentRomStart); 93 seqtblsize = (seqtblsize + 15 & ~15); 94 seqtblptr = alHeapAlloc(&sys_aheap, 1, seqtblsize); 95 //PRINTF_D(WHITE, "seqtblsize %d", seqtblsize); 96 //PRINTF_D(WHITE, "seqtblptr %x", (int)&seqtblptr); 97 98 //this call may result in decompression callbacks 99 wess_seq_loader_init(wess_get_master_status(), _doom64_wsdSegmentRomStart, NoOpenSeqHandle, seqtblptr, seqtblsize); 100 101 seqsize = wess_seq_range_sizeof(0, wess_seq_loader_count()); 102 seqtblsize = (seqsize + 15 & ~15); 103 seqptr = alHeapAlloc(&sys_aheap, 1, seqsize); 104 105 //PRINTF_D(WHITE, "seqsize %d", seqsize); 106 //PRINTF_D(WHITE, "seqptr %x", (int)&seqptr); 107 108 //this call may result in decompression callbacks 109 wess_seq_range_load(0, wess_seq_loader_count(), seqptr); 110 111 audioHeapEnd = (int)alHeapAlloc(&sys_aheap, 1, 4) - (int)&audio_heap; 112 audioHeapEnd += 16; 113 114 //PRINTF_D(WHITE, "audioHeapEnd %x", audioHeapEnd); 115 116 if (audioHeapEnd > AUDIO_HEAP_SIZE) 117 I_Error("S_Init: Audio heap overflow"); 118 119 S_SetSoundVolume(SfxVolume); 120 S_SetMusicVolume(MusVolume); 121 122 //PRINTF_D(WHITE, "S_Init: End"); 123 124 //while(1){} 125 } 126 127 void S_SetSoundVolume(int volume) // 800297A8 128 { 129 wess_master_sfx_vol_set((char)((volume * 85) / 100)); 130 } 131 132 void S_SetMusicVolume(int volume) // 800297F4 133 { 134 wess_master_mus_vol_set((char)((volume * 110) / 100)); 135 } 136 137 int music_sequence; // 8005b250 138 139 void S_StartMusic(int mus_seq) // 8002983C 140 { 141 if (disabledrawing == false) 142 { 143 wess_seq_trigger(mus_seq); 144 music_sequence = mus_seq; 145 } 146 } 147 148 void S_StopMusic(void) // 80029878 149 { 150 wess_seq_stop(music_sequence); 151 music_sequence = 0; 152 } 153 154 void S_PauseSound(void) // 800298A4 155 { 156 wess_seq_pauseall(YesMute, (REMEMBER_MUSIC|REMEMBER_SNDFX)); 157 } 158 159 void S_ResumeSound(void) // 800298C8 160 { 161 wess_seq_restartall(YesVoiceRestart); 162 } 163 164 void S_StopSound(mobj_t *origin,int seqnum) // 800298E8 165 { 166 if (!origin) 167 wess_seq_stop(seqnum); 168 else 169 wess_seq_stoptype((int)origin); 170 } 171 172 void S_StopAll(void) // 8002991C 173 { 174 wess_seq_stopall(); 175 } 176 177 #define SND_INACTIVE 0 178 #define SND_PLAYING 1 179 180 int S_SoundStatus(int seqnum) // 8002993C 181 { 182 if (wess_seq_status(seqnum) == SEQUENCE_PLAYING) 183 return SND_PLAYING; 184 else 185 return SND_INACTIVE; 186 } 187 188 void S_StartSound(mobj_t *origin, int sound_id) // 80029970 189 { 190 int flags; 191 int vol; 192 int pan; 193 TriggerPlayAttr attr; 194 195 if (disabledrawing == false) 196 { 197 if (origin && (origin != cameratarget)) 198 { 199 if (!S_AdjustSoundParams(cameratarget, origin, &vol, &pan)) 200 { 201 return; 202 } 203 } 204 else 205 { 206 vol = 127; 207 pan = 64; 208 } 209 210 attr.mask = (TRIGGER_VOLUME | TRIGGER_PAN | TRIGGER_REVERB); 211 attr.volume = (char)vol; 212 attr.pan = (char)pan; 213 214 attr.reverb = 0; 215 216 if (origin) 217 { 218 flags = origin->subsector->sector->flags; 219 220 if (flags & MS_REVERB) { 221 attr.reverb = 16; 222 } 223 else if (flags & MS_REVERBHEAVY) { 224 attr.reverb = 32; 225 } 226 } 227 228 wess_seq_trigger_type_special(sound_id, (unsigned long)origin, &attr); 229 } 230 } 231 232 #define S_CLIPPING_DIST (1700) 233 #define S_MAX_DIST (127 * S_CLIPPING_DIST) 234 #define S_CLOSE_DIST (200) 235 #define S_ATTENUATOR (S_CLIPPING_DIST - S_CLOSE_DIST) 236 #define S_STEREO_SWING (96) 237 238 int S_AdjustSoundParams(mobj_t *listener, mobj_t *origin, int* vol, int* pan) // 80029A48 239 { 240 fixed_t approx_dist; 241 angle_t angle; 242 243 approx_dist = P_AproxDistance(listener->x - origin->x, listener->y - origin->y); 244 approx_dist >>= FRACBITS; 245 246 if (approx_dist > S_CLIPPING_DIST) { 247 return 0; 248 } 249 250 if (listener->x != origin->x || listener->y != origin->y) 251 { 252 /* angle of source to listener */ 253 angle = R_PointToAngle2(listener->x, listener->y, origin->x, origin->y); 254 255 if (angle <= listener->angle) { 256 angle += 0xffffffff; 257 } 258 angle -= listener->angle; 259 260 /* stereo separation */ 261 *pan = (128 - ((finesine[angle >> ANGLETOFINESHIFT] * S_STEREO_SWING) >> FRACBITS)) >> 1; 262 } 263 else 264 { 265 *pan = 64; 266 } 267 268 /* volume calculation */ 269 if (approx_dist < S_CLOSE_DIST) 270 { 271 *vol = 127; 272 } 273 else 274 { 275 /* distance effect */ 276 approx_dist = -approx_dist; /* set neg */ 277 *vol = (((approx_dist << 7) - approx_dist) + S_MAX_DIST) / S_ATTENUATOR; 278 } 279 280 return (*vol > 0); 281 }