ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/audio.cpp
(Generate patch)

Comparing BasiliskII/src/audio.cpp (file contents):
Revision 1.7 by cebix, 2001-02-02T20:52:56Z vs.
Revision 1.13 by cebix, 2004-01-12T15:29:21Z

# Line 1 | Line 1
1   /*
2   *  audio.cpp - Audio support
3   *
4 < *  Basilisk II (C) 1997-2001 Christian Bauer
5 < *  Portions (C) 1997-1999 Marc Hellwig
4 > *  Basilisk II (C) 1997-2004 Christian Bauer
5 > *  Portions written by Marc Hellwig
6   *
7   *  This program is free software; you can redistribute it and/or modify
8   *  it under the terms of the GNU General Public License as published by
# Line 36 | Line 36
36   #include "debug.h"
37  
38  
39 + // Supported sample rates, sizes and channels
40 + vector<uint32> audio_sample_rates;
41 + vector<uint16> audio_sample_sizes;
42 + vector<uint16> audio_channel_counts;
43 +
44   // Global variables
45   struct audio_status AudioStatus;        // Current audio status (sample rate etc.)
46   bool audio_open = false;                        // Flag: audio is initialized and ready
# Line 65 | Line 70 | static int32 AudioGetInfo(uint32 infoPtr
70   {
71          D(bug(" AudioGetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
72          M68kRegisters r;
68        int i;
73  
74          switch (selector) {
75                  case siSampleSize:
# Line 73 | Line 77 | static int32 AudioGetInfo(uint32 infoPtr
77                          break;
78  
79                  case siSampleSizeAvailable: {
80 <                        r.d[0] = audio_num_sample_sizes * 2;
80 >                        r.d[0] = audio_sample_sizes.size() * 2;
81                          Execute68kTrap(0xa122, &r);     // NewHandle()
82                          uint32 h = r.a[0];
83                          if (h == 0)
84                                  return memFullErr;
85 <                        WriteMacInt16(infoPtr + sil_count, audio_num_sample_sizes);
85 >                        WriteMacInt16(infoPtr + sil_count, audio_sample_sizes.size());
86                          WriteMacInt32(infoPtr + sil_infoHandle, h);
87                          uint32 sp = ReadMacInt32(h);
88 <                        for (i=0; i<audio_num_sample_sizes; i++)
88 >                        for (unsigned i=0; i<audio_sample_sizes.size(); i++)
89                                  WriteMacInt16(sp + i*2, audio_sample_sizes[i]);
90                          break;
91                  }
# Line 91 | Line 95 | static int32 AudioGetInfo(uint32 infoPtr
95                          break;
96  
97                  case siChannelAvailable: {
98 <                        r.d[0] = audio_num_channel_counts * 2;
98 >                        r.d[0] = audio_channel_counts.size() * 2;
99                          Execute68kTrap(0xa122, &r);     // NewHandle()
100                          uint32 h = r.a[0];
101                          if (h == 0)
102                                  return memFullErr;
103 <                        WriteMacInt16(infoPtr + sil_count, audio_num_channel_counts);
103 >                        WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size());
104                          WriteMacInt32(infoPtr + sil_infoHandle, h);
105                          uint32 sp = ReadMacInt32(h);
106 <                        for (i=0; i<audio_num_channel_counts; i++)
106 >                        for (unsigned i=0; i<audio_channel_counts.size(); i++)
107                                  WriteMacInt16(sp + i*2, audio_channel_counts[i]);
108                          break;
109                  }
# Line 109 | Line 113 | static int32 AudioGetInfo(uint32 infoPtr
113                          break;
114  
115                  case siSampleRateAvailable: {
116 <                        r.d[0] = audio_num_sample_rates * 4;
116 >                        r.d[0] = audio_sample_rates.size() * 4;
117                          Execute68kTrap(0xa122, &r);     // NewHandle()
118                          uint32 h = r.a[0];
119                          if (h == 0)
120                                  return memFullErr;
121 <                        WriteMacInt16(infoPtr + sil_count, audio_num_sample_rates);
121 >                        WriteMacInt16(infoPtr + sil_count, audio_sample_rates.size());
122                          WriteMacInt32(infoPtr + sil_infoHandle, h);
123                          uint32 lp = ReadMacInt32(h);
124 <                        for (i=0; i<audio_num_sample_rates; i++)
124 >                        for (unsigned i=0; i<audio_sample_rates.size(); i++)
125                                  WriteMacInt32(lp + i*4, audio_sample_rates[i]);
126                          break;
127                  }
# Line 130 | Line 134 | static int32 AudioGetInfo(uint32 infoPtr
134                          WriteMacInt32(infoPtr, audio_get_speaker_volume());
135                          break;
136  
133                case siHeadphoneMute:
134                        WriteMacInt16(infoPtr, 0);
135                        break;
136
137                case siHeadphoneVolume:
138                        WriteMacInt32(infoPtr, 0x01000100);
139                        break;
140
141                case siHeadphoneVolumeSteps:
142                        WriteMacInt16(infoPtr, 13);
143                        break;
144
137                  case siHardwareMute:
138                          WriteMacInt16(infoPtr, audio_get_main_mute());
139                          break;
# Line 151 | Line 143 | static int32 AudioGetInfo(uint32 infoPtr
143                          break;
144  
145                  case siHardwareVolumeSteps:
146 <                        WriteMacInt16(infoPtr, 13);
146 >                        WriteMacInt16(infoPtr, 7);
147                          break;
148  
149                  case siHardwareBusy:
150                          WriteMacInt16(infoPtr, AudioStatus.num_sources != 0);
151                          break;
152  
153 +                case siHardwareFormat:
154 +                        WriteMacInt32(infoPtr + scd_flags, 0);
155 +                        WriteMacInt32(infoPtr + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
156 +                        WriteMacInt16(infoPtr + scd_numChannels, AudioStatus.channels);
157 +                        WriteMacInt16(infoPtr + scd_sampleSize, AudioStatus.sample_size);
158 +                        WriteMacInt32(infoPtr + scd_sampleRate, AudioStatus.sample_rate);
159 +                        WriteMacInt32(infoPtr + scd_sampleCount, audio_frames_per_block);
160 +                        WriteMacInt32(infoPtr + scd_buffer, 0);
161 +                        WriteMacInt32(infoPtr + scd_reserved, 0);
162 +                        break;
163 +
164                  default:        // Delegate to Apple Mixer
165                          if (AudioStatus.mixer == 0)
166                                  return badComponentSelector;
# Line 182 | Line 185 | static int32 AudioSetInfo(uint32 infoPtr
185   {
186          D(bug(" AudioSetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
187          M68kRegisters r;
185        int i;
188  
189          switch (selector) {
190                  case siSampleSize:
191                          D(bug("  set sample size %08lx\n", infoPtr));
192                          if (AudioStatus.num_sources)
193                                  return siDeviceBusyErr;
194 <                        for (i=0; i<audio_num_sample_sizes; i++)
194 >                        if (infoPtr == AudioStatus.sample_size)
195 >                                return noErr;
196 >                        for (unsigned i=0; i<audio_sample_sizes.size(); i++)
197                                  if (audio_sample_sizes[i] == infoPtr) {
198 <                                        audio_set_sample_size(i);
199 <                                        return noErr;
198 >                                        if (audio_set_sample_size(i))
199 >                                                return noErr;
200 >                                        else
201 >                                                return siInvalidSampleSize;
202                                  }
203                          return siInvalidSampleSize;
204  
# Line 200 | Line 206 | static int32 AudioSetInfo(uint32 infoPtr
206                          D(bug("  set sample rate %08lx\n", infoPtr));
207                          if (AudioStatus.num_sources)
208                                  return siDeviceBusyErr;
209 <                        for (i=0; i<audio_num_sample_rates; i++)
209 >                        if (infoPtr == AudioStatus.sample_rate)
210 >                                return noErr;
211 >                        for (unsigned i=0; i<audio_sample_rates.size(); i++)
212                                  if (audio_sample_rates[i] == infoPtr) {
213 <                                        audio_set_sample_rate(i);
214 <                                        return noErr;
213 >                                        if (audio_set_sample_rate(i))
214 >                                                return noErr;
215 >                                        else
216 >                                                return siInvalidSampleRate;
217                                  }
218                          return siInvalidSampleRate;
219  
# Line 211 | Line 221 | static int32 AudioSetInfo(uint32 infoPtr
221                          D(bug("  set number of channels %08lx\n", infoPtr));
222                          if (AudioStatus.num_sources)
223                                  return siDeviceBusyErr;
224 <                        for (i=0; i<audio_num_channel_counts; i++)
224 >                        if (infoPtr == AudioStatus.channels)
225 >                                return noErr;
226 >                        for (unsigned i=0; i<audio_channel_counts.size(); i++)
227                                  if (audio_channel_counts[i] == infoPtr) {
228 <                                        audio_set_channels(i);
229 <                                        return noErr;
228 >                                        if (audio_set_channels(i))
229 >                                                return noErr;
230 >                                        else
231 >                                                return badChannel;
232                                  }
233                          return badChannel;
234  
# Line 227 | Line 241 | static int32 AudioSetInfo(uint32 infoPtr
241                          audio_set_speaker_volume(infoPtr);
242                          break;
243  
230                case siHeadphoneMute:
231                case siHeadphoneVolume:
232                        break;
233
244                  case siHardwareMute:
245                          audio_set_main_mute((uint16)infoPtr);
246                          break;
# Line 264 | Line 274 | int32 AudioDispatch(uint32 params, uint3
274          D(bug("AudioDispatch params %08lx (size %d), what %d\n", params, ReadMacInt8(params + cp_paramSize), (int16)ReadMacInt16(params + cp_what)));
275          M68kRegisters r;
276          uint32 p = params + cp_params;
277 +        int16 selector = (int16)ReadMacInt16(params + cp_what);
278 +
279 +        switch (selector) {
280  
281 <        switch ((int16)ReadMacInt16(params + cp_what)) {
269 <                // Basic component functions
281 >                // General component functions
282                  case kComponentOpenSelect:
283                          if (audio_data == 0) {
284  
285                                  // Allocate global data area
286                                  r.d[0] = SIZEOF_adat;
287 <                                Execute68kTrap(0xa71e, &r);     // NewPtrSysClear()
287 >                                Execute68kTrap(0xa040, &r);     // ResrvMem()
288 >                                r.d[0] = SIZEOF_adat;
289 >                                Execute68kTrap(0xa31e, &r);     // NewPtrClear()
290                                  if (r.a[0] == 0)
291                                          return memFullErr;
292                                  audio_data = r.a[0];
# Line 359 | Line 373 | int32 AudioDispatch(uint32 params, uint3
373                                  WriteMacInt16(p, 0xa82a); p += 2;       // ComponentDispatch
374                                  WriteMacInt16(p, 0x201f); p += 2;       // move.l       (sp)+,d0
375                                  WriteMacInt16(p, M68K_RTS); p += 2;     // rts
376 +                                if (p - audio_data != adatStartSource)
377 +                                        goto adat_error;
378 +                                WriteMacInt16(p, 0x598f); p += 2;       // subq.l       #4,sp
379 +                                WriteMacInt16(p, 0x2f09); p += 2;       // move.l       a1,-(sp)
380 +                                WriteMacInt16(p, 0x3f00); p += 2;       // move.w       d0,-(sp)
381 +                                WriteMacInt16(p, 0x2f08); p += 2;       // move.l       a0,-(sp)
382 +                                WriteMacInt16(p, 0x2f3c); p += 2;       // move.l       #$00060105,-(sp)
383 +                                WriteMacInt32(p, 0x00060105); p+= 4;
384 +                                WriteMacInt16(p, 0x7000); p += 2;       // moveq        #0,d0
385 +                                WriteMacInt16(p, 0xa82a); p += 2;       // ComponentDispatch
386 +                                WriteMacInt16(p, 0x201f); p += 2;       // move.l       (sp)+,d0
387 +                                WriteMacInt16(p, M68K_RTS); p += 2;     // rts
388                                  if (p - audio_data != adatData)
389                                          goto adat_error;
390                          }
# Line 372 | Line 398 | adat_error:    printf("FATAL: audio compone
398                          QuitEmulator();
399                          return openErr;
400  
375                case kComponentCanDoSelect:
376                case kComponentRegisterSelect:
377                        return noErr;
378
379                case kComponentVersionSelect:
380                        return 0x00010003;
381
401                  case kComponentCloseSelect:
402                          open_count--;
403                          if (open_count == 0) {
404 <                                if (AudioStatus.mixer) {
405 <                                        // Close Apple Mixer
406 <                                        r.a[0] = AudioStatus.mixer;
407 <                                        Execute68k(audio_data + adatCloseMixer, &r);
408 <                                        AudioStatus.mixer = 0;
409 <                                        return r.d[0];
404 >                                if (audio_data) {
405 >                                        if (AudioStatus.mixer) {
406 >                                                // Close Apple Mixer
407 >                                                r.a[0] = AudioStatus.mixer;
408 >                                                Execute68k(audio_data + adatCloseMixer, &r);
409 >                                                AudioStatus.mixer = 0;
410 >                                                return r.d[0];
411 >                                        }
412 >                                        r.a[0] = audio_data;
413 >                                        Execute68kTrap(0xa01f, &r);     // DisposePtr()
414 >                                        audio_data = 0;
415                                  }
416                                  AudioStatus.num_sources = 0;
417                                  audio_exit_stream();
418                          }
419                          return noErr;
420  
421 <                // Sound component functions
421 >                case kComponentCanDoSelect:
422 >                        switch ((int16)ReadMacInt16(p)) {
423 >                                case kComponentOpenSelect:
424 >                                case kComponentCloseSelect:
425 >                                case kComponentCanDoSelect:
426 >                                case kComponentVersionSelect:
427 >                                case kComponentRegisterSelect:
428 >                                case kSoundComponentInitOutputDeviceSelect:
429 >                                case kSoundComponentGetSourceSelect:
430 >                                case kSoundComponentGetInfoSelect:
431 >                                case kSoundComponentSetInfoSelect:
432 >                                case kSoundComponentStartSourceSelect:
433 >                                        return 1;
434 >                                default:
435 >                                        return 0;
436 >                        }
437 >
438 >                case kComponentVersionSelect:
439 >                        return 0x00010003;
440 >
441 >                case kComponentRegisterSelect:
442 >                        return noErr;
443 >
444 >                // Sound component functions (not delegated)
445                  case kSoundComponentInitOutputDeviceSelect:
446                          D(bug(" InitOutputDevice\n"));
447                          if (!audio_open)
# Line 422 | Line 469 | adat_error:    printf("FATAL: audio compone
469                          D(bug(" OpenMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
470                          return r.d[0];
471  
472 +                case kSoundComponentGetSourceSelect:
473 +                        D(bug(" GetSource source %08lx\n", ReadMacInt32(p)));
474 +                        WriteMacInt32(ReadMacInt32(p), AudioStatus.mixer);
475 +                        return noErr;
476 +
477 +                // Sound component functions (delegated)
478                  case kSoundComponentAddSourceSelect:
479                          D(bug(" AddSource\n"));
480                          AudioStatus.num_sources++;
# Line 432 | Line 485 | adat_error:    printf("FATAL: audio compone
485                          AudioStatus.num_sources--;
486                          goto delegate;
487  
488 +                case kSoundComponentGetInfoSelect:
489 +                        return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
490 +
491 +                case kSoundComponentSetInfoSelect:
492 +                        return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
493 +
494 +                case kSoundComponentStartSourceSelect:
495 +                        D(bug(" StartSource count %d\n", ReadMacInt16(p + 4)));
496 +                        D(bug(" starting Apple Mixer\n"));
497 +                        r.d[0] = ReadMacInt16(p + 4);
498 +                        r.a[0] = ReadMacInt32(p);
499 +                        r.a[1] = AudioStatus.mixer;
500 +                        Execute68k(audio_data + adatStartSource, &r);
501 +                        D(bug(" returns %08lx\n", r.d[0]));
502 +                        return noErr;
503 +
504                  case kSoundComponentStopSourceSelect:
505                          D(bug(" StopSource\n"));
506                          goto delegate;
# Line 446 | Line 515 | delegate:      // Delegate call to Apple Mixe
515                          D(bug(" returns %08lx\n", r.d[0]));
516                          return r.d[0];
517  
449                case kSoundComponentStartSourceSelect:
450                        D(bug(" StartSource\n"));
451                        return noErr;
452
453                case kSoundComponentGetInfoSelect:
454                        return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
455
456                case kSoundComponentSetInfoSelect:
457                        return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
458
518                  case kSoundComponentPlaySourceBufferSelect:
519 <                        D(bug(" PlaySourceBuffer\n"));
519 >                        D(bug(" PlaySourceBuffer flags %08lx\n", ReadMacInt32(p)));
520                          r.d[0] = ReadMacInt32(p);
521                          r.a[0] = ReadMacInt32(p + 4);
522                          r.a[1] = ReadMacInt32(p + 8);
# Line 467 | Line 526 | delegate:      // Delegate call to Apple Mixe
526                          return r.d[0];
527  
528                  default:
529 <                        return badComponentSelector;
529 >                        if (selector >= 0x100)
530 >                                goto delegate;
531 >                        else
532 >                                return badComponentSelector;
533          }
534   }
535  
# Line 549 | Line 611 | int16 SoundInStatus(uint32 pb, uint32 dc
611  
612                  case siDeviceIcon: {
613                          M68kRegisters r;
614 <                        static const uint16 proc[] = {
615 <                                0x558f,                                 //      subq.l  #2,sp
616 <                                0xa994,                                 //      CurResFile
617 <                                0x4267,                                 //      clr.w   -(sp)
618 <                                0xa998,                                 //      UseResFile
619 <                                0x598f,                                 //      subq.l  #4,sp
620 <                                0x4879, 0x4943, 0x4e23, //      move.l  #'ICN#',-(sp)
621 <                                0x3f3c, 0xbf76,                 //      move.w  #-16522,-(sp)
622 <                                0xa9a0,                                 //      GetResource
623 <                                0x245f,                                 //      move.l  (sp)+,a2
624 <                                0xa998,                                 //      UseResFile
625 <                                0x200a,                                 //      move.l  a2,d0
626 <                                0x6604,                                 //      bne             1
627 <                                0x7000,                                 //  moveq       #0,d0
628 <                                M68K_RTS,
629 <                                0x2f0a,                                 //1 move.l      a2,-(sp)
630 <                                0xa992,                                 //  DetachResource
631 <                                0x204a,                                 //  move.l      a2,a0
632 <                                0xa04a,                                 //      HNoPurge
633 <                                0x7001,                                 //      moveq   #1,d0
634 <                                M68K_RTS
614 >                        static const uint8 proc[] = {
615 >                                0x55, 0x8f,                                                     //      subq.l  #2,sp
616 >                                0xa9, 0x94,                                                     //      CurResFile
617 >                                0x42, 0x67,                                                     //      clr.w   -(sp)
618 >                                0xa9, 0x98,                                                     //      UseResFile
619 >                                0x59, 0x8f,                                                     //      subq.l  #4,sp
620 >                                0x48, 0x79, 0x49, 0x43, 0x4e, 0x23,     //      move.l  #'ICN#',-(sp)
621 >                                0x3f, 0x3c, 0xbf, 0x76,                         //      move.w  #-16522,-(sp)
622 >                                0xa9, 0xa0,                                                     //      GetResource
623 >                                0x24, 0x5f,                                                     //      move.l  (sp)+,a2
624 >                                0xa9, 0x98,                                                     //      UseResFile
625 >                                0x20, 0x0a,                                                     //      move.l  a2,d0
626 >                                0x66, 0x04,                                                     //      bne             1
627 >                                0x70, 0x00,                                                     //  moveq       #0,d0
628 >                                M68K_RTS >> 8, M68K_RTS & 0xff,
629 >                                0x2f, 0x0a,                                                     //1 move.l      a2,-(sp)
630 >                                0xa9, 0x92,                                                     //  DetachResource
631 >                                0x20, 0x4a,                                                     //  move.l      a2,a0
632 >                                0xa0, 0x4a,                                                     //      HNoPurge
633 >                                0x70, 0x01,                                                     //      moveq   #1,d0
634 >                                M68K_RTS >> 8, M68K_RTS & 0xff
635                          };
636                          Execute68k((uint32)proc, &r);
637                          if (r.d[0]) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines