diff -ru old/CSynthMT32.cpp new/CSynthMT32.cpp
old
|
new
|
|
2976 | 2976 | //LOG_MSG("f num %d freq %d and fa %d", f, freq, fa); |
2977 | 2977 | |
2978 | 2978 | |
2979 | | waveforms[0][f] = (Bit16s *)malloc(fa*2); |
2980 | | waveforms[1][f] = (Bit16s *)malloc(fa*2); |
2981 | | waveforms[2][f] = (Bit16s *)malloc(fa*2); |
2982 | | waveforms[3][f] = (Bit16s *)malloc(fa*4); |
2983 | | |
2984 | 2979 | waveformsize[0][f] = waveformsize[1][f] = waveformsize[2][f] = fa*2; |
2985 | 2980 | waveformsize[3][f] = fa*4; |
2986 | 2981 | |
2987 | | memcpy(waveforms[0][f], &tmpforms[0][0],fa*2); |
2988 | | memcpy(waveforms[1][f], &tmpforms[1][0],fa*2); |
2989 | | memcpy(waveforms[2][f], &tmpforms[2][0],fa*2); |
2990 | | memcpy(waveforms[3][f], &tmpforms[3][0],fa*4); |
2991 | | |
2992 | | |
2993 | | int out; |
2994 | | |
2995 | | out = fp.write(waveforms[0][f],divtable[f]>>13); |
2996 | | out = fp.write(waveforms[1][f],divtable[f]>>13); |
2997 | | out = fp.write(waveforms[2][f],divtable[f]>>13); |
2998 | | out = fp.write(waveforms[3][f],divtable[f]>>12); |
2999 | | |
3000 | | |
| 2982 | for (int i = 0; i < 4; ++i) { |
| 2983 | waveforms[i][f] = (Bit16s *)malloc(waveformsize[i][f]); |
| 2984 | memcpy(waveforms[i][f], &tmpforms[i][0],waveformsize[i][f]); |
| 2985 | // TODO / FIXME: The following code is not endian safe! |
| 2986 | out = fp.write(waveforms[i][f],waveformsize[i][f]); |
| 2987 | } |
3001 | 2988 | #else |
3002 | | waveforms[0][f] = (Bit16s *)malloc(divtable[f]>>13); |
3003 | | waveforms[1][f] = (Bit16s *)malloc(divtable[f]>>13); |
3004 | | waveforms[2][f] = (Bit16s *)malloc(divtable[f]>>13); |
3005 | | waveforms[3][f] = (Bit16s *)malloc(divtable[f]>>12); |
3006 | | |
3007 | 2989 | waveformsize[0][f] = waveformsize[1][f] = waveformsize[2][f] = divtable[f]>>13; |
3008 | 2990 | waveformsize[3][f] = divtable[f]>>12; |
3009 | 2991 | |
3010 | | fp.read(waveforms[0][f],divtable[f]>>13); |
3011 | | fp.read(waveforms[1][f],divtable[f]>>13); |
3012 | | fp.read(waveforms[2][f],divtable[f]>>13); |
3013 | | fp.read(waveforms[3][f],divtable[f]>>12); |
| 2992 | for (int i = 0; i < 4; ++i) { |
| 2993 | waveforms[i][f] = (Bit16s *)malloc(waveformsize[i][f]); |
| 2994 | for (int j = 0; j < waveformsize[i][f]/2; ++j) |
| 2995 | waveforms[i][f][j] = fp.readSint16LE(); |
| 2996 | } |
3014 | 2997 | #endif |
3015 | 2998 | |
3016 | 2999 | |
… |
… |
|
3600 | 3583 | } |
3601 | 3584 | |
3602 | 3585 | while(!fp.eof()) { |
3603 | | fp.read(&c, 1); |
| 3586 | c = fp.readByte(); |
3604 | 3587 | sysexBuf[syslen] = c; |
3605 | 3588 | syslen++; |
3606 | 3589 | if(c==0xf0) { |
… |
… |
|
3859 | 3842 | //Bit32s maxamp = 0; |
3860 | 3843 | while (!fIn.eof()) { |
3861 | 3844 | Bit16s s, c1; |
3862 | | |
3863 | | fIn.read(&s, 1); |
3864 | | fIn.read(&c1, 1); |
| 3845 | |
| 3846 | s = fIn.readByte(); |
| 3847 | c1 = fIn.readByte(); |
| 3848 | |
3865 | 3849 | /* |
3866 | 3850 | int e,z,u,bit; |
3867 | 3851 | |
… |
… |
|
3896 | 3880 | int bit; |
3897 | 3881 | int u; |
3898 | 3882 | |
3899 | | int order[16] = {0, 9,1 ,2, 3, 4, 5, 6, 7, 10, 11, 12,13, 14, 15,8}; |
| 3883 | static const int order[16] = {0, 9,1 ,2, 3, 4, 5, 6, 7, 10, 11, 12,13, 14, 15,8}; |
3900 | 3884 | |
3901 | 3885 | e=0; |
3902 | 3886 | z = 15; |
… |
… |
|
3960 | 3944 | } |
3961 | 3945 | |
3962 | 3946 | // For resetting mt32 mid-execution |
3963 | | memcpy(&mt32default, &mt32ram,sizeof(mt32ram)); |
| 3947 | memcpy(&mt32default, &mt32ram, sizeof(mt32ram)); |
3964 | 3948 | |
3965 | 3949 | if (!InitTables(baseDir)) return false; |
3966 | 3950 | if(myProp.UseDefault) { |
… |
… |
|
3977 | 3961 | } |
3978 | 3962 | activeChannels = 0; |
3979 | 3963 | |
| 3964 | #ifdef HAVE_X86 |
3980 | 3965 | bool useSSE = false, use3DNow = false; |
3981 | 3966 | |
3982 | | #ifdef HAVE_X86 |
3983 | 3967 | use3DNow = Detect3DNow(); |
3984 | 3968 | useSSE = DetectSIMD(); |
3985 | 3969 | |
… |
… |
|
4003 | 3987 | |
4004 | 3988 | #endif |
4005 | 3989 | |
4006 | | _audioStream = makeAppendableAudioStream(32000, SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN, 4096); |
4007 | | _rateConverter = makeRateConverter(32000, myProp.OutRate, true, false); |
4008 | | |
4009 | 3990 | return true; |
4010 | 3991 | } |
4011 | 3992 | |
… |
… |
|
4021 | 4002 | } |
4022 | 4003 | |
4023 | 4004 | #endif |
4024 | | delete _rateConverter; |
4025 | | delete _audioStream; |
4026 | 4005 | |
4027 | 4006 | isOpen=false; |
4028 | 4007 | |
… |
… |
|
4155 | 4134 | |
4156 | 4135 | Bit32u addr; |
4157 | 4136 | Bit32u *header; |
4158 | | unsigned int off,m; |
| 4137 | unsigned int off; |
| 4138 | int m; |
4159 | 4139 | header = (Bit32u *)(sysex+1); |
4160 | | mt32ramFormat *myMem; |
4161 | | myMem = &mt32ram; |
4162 | 4140 | //int dummy = 0; |
4163 | 4141 | Bit32s lens = len; |
4164 | 4142 | |
… |
… |
|
4381 | 4359 | |
4382 | 4360 | |
4383 | 4361 | |
4384 | | static Bit16s tmpBuffer[4096], tmpBuffer2[4096]; |
| 4362 | static Bit16s tmpBuffer[4096]; |
4385 | 4363 | static float sndbufl[4096]; |
4386 | 4364 | static float sndbufr[4096]; |
4387 | 4365 | static float outbufl[4096]; |
… |
… |
|
4400 | 4378 | snd = (Bit16s *)stream; |
4401 | 4379 | if(!isEnabled) return; |
4402 | 4380 | memset(stream,0,len*4); |
4403 | | memset(tmpBuffer2,0,4096); |
4404 | | useBuf = &tmpBuffer[0]; |
| 4381 | useBuf = snd; |
4405 | 4382 | |
4406 | | if (myProp.OutRate != 32000) |
4407 | | outlen = len * 32000 / myProp.OutRate; |
4408 | | else |
4409 | | outlen = len; |
| 4383 | outlen = len; |
4410 | 4384 | |
4411 | 4385 | assert(len < 1024); // tmpBuffer is 4096 bytes |
4412 | 4386 | /* |
… |
… |
|
4428 | 4402 | |
4429 | 4403 | if(partTable[i]->produceOutput(tmpBuffer,outlen)==true) { |
4430 | 4404 | #if USE_MMX == 0 |
4431 | | Bit16s *tmpoff = tmpBuffer2; |
| 4405 | Bit16s *tmpoff = snd; |
4432 | 4406 | int q = 0; |
4433 | 4407 | for(m=0;m<(Bit32s)outlen;m++) { |
4434 | 4408 | tmpoff[q] += (Bit16s)(((Bit32s)tmpBuffer[q] * (Bit32s)mastervolume)>>15); |
… |
… |
|
4450 | 4424 | psllq mm3, 32 |
4451 | 4425 | por mm3,mm2 |
4452 | 4426 | mov esi, useBuf |
4453 | | mov edi, tmpBuffer2 |
| 4427 | mov edi, snd |
4454 | 4428 | mixloop4: |
4455 | 4429 | movq mm1, [esi] |
4456 | 4430 | movq mm2, [edi] |
… |
… |
|
4467 | 4441 | emms |
4468 | 4442 | } |
4469 | 4443 | #else |
4470 | | atti386_produceOutput1(tmplen, mastervolume, useBuf, tmpBuffer2); |
| 4444 | atti386_produceOutput1(tmplen, mastervolume, useBuf, snd); |
4471 | 4445 | #endif |
4472 | 4446 | #endif |
4473 | 4447 | } |
4474 | 4448 | } |
4475 | 4449 | |
4476 | | //memcpy(snd, tmpBuffer2, len * 4); |
4477 | | _audioStream->append((byte *)tmpBuffer2, outlen * 4); |
4478 | | _rateConverter->flow(*_audioStream, snd, len, volume, volume); |
4479 | | |
4480 | 4450 | if(myProp.UseReverb) { |
4481 | 4451 | #if USE_MMX == 3 |
4482 | 4452 | if(!usingSIMD) { |
diff -ru old/MT32Structures.h new/MT32Structures.h
old
|
new
|
|
603 | 603 | union soundaddr { |
604 | 604 | Bit32u pcmabs; |
605 | 605 | struct offsets { |
| 606 | #if defined(SCUMM_LITTLE_ENDIAN) |
606 | 607 | Bit16u pcmoffset; |
607 | 608 | Bit16u pcmplace; |
| 609 | #else |
| 610 | Bit16u pcmplace; |
| 611 | Bit16u pcmoffset; |
| 612 | #endif |
608 | 613 | } pcmoffs; |
609 | 614 | }; |
610 | 615 | |
diff -ru old/SynthMT32.h new/SynthMT32.h
old
|
new
|
|
54 | 54 | //#define WGAMP (8192) |
55 | 55 | |
56 | 56 | #include "backends/midi/MT32Structures.h" |
57 | | #include "sound/audiostream.h" |
58 | | #include "sound/rate.h" |
59 | 57 | #include "sound/mixer.h" |
60 | 58 | |
61 | 59 | // Function that detects the availablity of SSE SIMD instructions |
… |
… |
|
68 | 66 | struct SynthProperties { |
69 | 67 | // Sample rate to use in mixing |
70 | 68 | int SampleRate; |
71 | | |
72 | | // Sample rate for output |
73 | | int OutRate; |
74 | | |
75 | 69 | // Flag to activate reverb. True = use reverb, False = no reverb |
76 | 70 | bool UseReverb; |
77 | 71 | // Flag True to use software set reverb settings, Flag False to set reverb settings in |
… |
… |
|
143 | 137 | unsigned char initmode; |
144 | 138 | bool isOpen; |
145 | 139 | SynthProperties myProp; |
146 | | AppendableAudioStream *_audioStream; |
147 | | RateConverter *_rateConverter; |
148 | 140 | |
149 | 141 | bool InitTables(const char * baseDir); |
150 | 142 | |
diff -ru old/mt32.cpp new/mt32.cpp
old
|
new
|
|
22 | 22 | * $Header$ |
23 | 23 | */ |
24 | 24 | |
25 | | #include "stdafx.h" |
| 25 | #include "emumidi.h" |
| 26 | |
26 | 27 | #include "common/util.h" |
27 | 28 | #include "common/file.h" |
28 | | #include "sound/mididrv.h" |
29 | | #include "sound/mixer.h" |
30 | 29 | |
31 | 30 | #include "SynthMT32.h" |
32 | 31 | |
33 | | #define BASE_FREQ 250 |
34 | | |
35 | | const char *rom_path; |
36 | | bool enabledSSE = true; |
37 | | bool enabled3DNow = false; |
38 | | |
39 | | class MidiDriver_MT32; |
40 | | |
41 | | class MidiDriver_MT32 : public MidiDriver { |
| 32 | class MidiDriver_MT32 : public MidiDriver_Emulated { |
42 | 33 | private: |
43 | 34 | CSynthMT32 *_synth; |
44 | | SoundMixer *_mixer; |
45 | | bool _isOpen; |
46 | | int _tempo; |
47 | | |
48 | | typedef void TimerCallback(void *); |
49 | | TimerCallback *_timer_proc; |
50 | | void *_timer_param; |
| 35 | |
| 36 | const char *rom_path; |
51 | 37 | |
52 | 38 | protected: |
53 | 39 | void generate_samples(int16 *buf, int len); |
54 | | static void premix_proc(void *param, int16 *buf, uint len); |
55 | 40 | |
56 | 41 | public: |
57 | 42 | MidiDriver_MT32(SoundMixer *mixer, const char *path); |
… |
… |
|
65 | 50 | void setPitchBendRange(byte channel, uint range) { } |
66 | 51 | void sysEx(byte *msg, uint16 length); |
67 | 52 | |
68 | | void setTimerCallback(void *timer_param, Timer::TimerProc timer_proc); |
69 | | uint32 getBaseTempo() { return 8000; } // 32000->8000 11025->11025 |
70 | | |
71 | 53 | MidiChannel *allocateChannel() { return 0; } |
72 | 54 | MidiChannel *getPercussionChannel() { return 0; } |
| 55 | |
| 56 | |
| 57 | // AudioStream API |
| 58 | bool isStereo() const { return true; } |
| 59 | int getRate() const { return 32000; } |
73 | 60 | }; |
74 | 61 | |
75 | 62 | |
… |
… |
|
80 | 67 | //////////////////////////////////////// |
81 | 68 | |
82 | 69 | |
83 | | MidiDriver_MT32::MidiDriver_MT32(SoundMixer *mixer, const char *path) : |
84 | | _mixer(mixer) { |
| 70 | MidiDriver_MT32::MidiDriver_MT32(SoundMixer *mixer, const char *path) |
| 71 | : MidiDriver_Emulated(mixer) { |
85 | 72 | _synth = new CSynthMT32(); |
86 | | _isOpen = false; |
87 | | _tempo = _mixer->getOutputRate(); //32000; // Do not change this |
88 | 73 | rom_path = path; |
89 | | _timer_proc = NULL; |
90 | 74 | File::addDefaultDirectory(path); |
91 | 75 | } |
92 | 76 | |
… |
… |
|
100 | 84 | if (_isOpen) |
101 | 85 | return MERR_ALREADY_OPEN; |
102 | 86 | |
103 | | prop.SampleRate = 32000; // 32000; |
| 87 | MidiDriver_Emulated::open(); |
| 88 | |
| 89 | prop.SampleRate = getRate(); // 32000; |
104 | 90 | prop.UseReverb = true; |
105 | 91 | prop.UseDefault = true; |
106 | 92 | //prop.RevType = 0; |
107 | 93 | //prop.RevTime = 5; |
108 | 94 | //prop.RevLevel = 3; |
109 | | prop.OutRate = _tempo; |
110 | | |
111 | | _mixer->setupPremix(premix_proc, this); |
112 | 95 | |
113 | 96 | _synth->ClassicOpen(rom_path, prop); |
114 | 97 | |
115 | | _isOpen = true; |
| 98 | _mixer->setupPremix(this); |
| 99 | |
116 | 100 | return 0; |
117 | 101 | } |
118 | 102 | |
… |
… |
|
125 | 109 | } |
126 | 110 | |
127 | 111 | void MidiDriver_MT32::close() { |
128 | | if (_isOpen) |
129 | | _synth->Close(); |
130 | | |
| 112 | if (!_isOpen) |
| 113 | return; |
131 | 114 | _isOpen = false; |
132 | | } |
133 | 115 | |
134 | | void MidiDriver_MT32::setTimerCallback(void *timer_param, Timer::TimerProc timer_proc) { |
135 | | _timer_proc = timer_proc; |
136 | | _timer_param = timer_param; |
137 | | } |
| 116 | // Detach the premix callback handler |
| 117 | _mixer->setupPremix(0); |
138 | 118 | |
139 | | void MidiDriver_MT32::premix_proc(void *param, int16 *buf, uint len) { |
140 | | ((MidiDriver_MT32 *) param)->generate_samples(buf, len); |
| 119 | _synth->Close(); |
141 | 120 | } |
142 | 121 | |
143 | 122 | void MidiDriver_MT32::generate_samples(int16 *data, int len) { |
144 | | int16 *p = data; |
145 | | |
146 | | memset(data, 0, len * 4); |
147 | | |
148 | | // With original frequency sound |
149 | | for (int i = 0; i < 8; i++) { |
150 | | _synth->MT32_CallBack((Bit8u *)p, len >> 3, _mixer->getMusicVolume()); |
151 | | if (_timer_proc) |
152 | | (*_timer_proc)(_timer_param); |
153 | | p += len >> 2; |
154 | | } |
| 123 | _synth->MT32_CallBack((Bit8u *)data, len, _mixer->getMusicVolume()); |
155 | 124 | } |
156 | 125 | |
157 | 126 | |
… |
… |
|
164 | 133 | MidiDriver *MidiDriver_MT32_create(SoundMixer *mixer, const char *path) { |
165 | 134 | return new MidiDriver_MT32(mixer, path); |
166 | 135 | } |
167 | | |