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.3 by cebix, 2000-04-10T18:52:18Z 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-2000 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 48 | Line 53 | bool AudioAvailable = false;           // Flag: a
53  
54  
55   /*
56 + *  Reset audio emulation
57 + */
58 +
59 + void AudioReset(void)
60 + {
61 +        audio_data = 0;
62 + }
63 +
64 +
65 + /*
66   *  Get audio info
67   */
68  
# Line 55 | 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;
58        int i;
73  
74          switch (selector) {
75                  case siSampleSize:
# Line 63 | 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 81 | 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 99 | 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 120 | Line 134 | static int32 AudioGetInfo(uint32 infoPtr
134                          WriteMacInt32(infoPtr, audio_get_speaker_volume());
135                          break;
136  
123                case siHeadphoneMute:
124                        WriteMacInt16(infoPtr, 0);
125                        break;
126
127                case siHeadphoneVolume:
128                        WriteMacInt32(infoPtr, 0x01000100);
129                        break;
130
131                case siHeadphoneVolumeSteps:
132                        WriteMacInt16(infoPtr, 13);
133                        break;
134
137                  case siHardwareMute:
138                          WriteMacInt16(infoPtr, audio_get_main_mute());
139                          break;
# Line 141 | 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 172 | 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;
175        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 190 | 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 201 | 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 217 | Line 241 | static int32 AudioSetInfo(uint32 infoPtr
241                          audio_set_speaker_volume(infoPtr);
242                          break;
243  
220                case siHeadphoneMute:
221                case siHeadphoneVolume:
222                        break;
223
244                  case siHardwareMute:
245                          audio_set_main_mute((uint16)infoPtr);
246                          break;
# Line 254 | 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)) {
259 <                // 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 349 | 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 362 | Line 398 | adat_error:    printf("FATAL: audio compone
398                          QuitEmulator();
399                          return openErr;
400  
365                case kComponentCanDoSelect:
366                case kComponentRegisterSelect:
367                        return noErr;
368
369                case kComponentVersionSelect:
370                        return 0x00010003;
371
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 394 | Line 451 | adat_error:    printf("FATAL: audio compone
451  
452                          // Init sound component data
453                          WriteMacInt32(audio_data + adatData + scd_flags, 0);
454 <                        WriteMacInt32(audio_data + adatData + scd_format, AudioStatus.sample_size == 16 ? 'twos' : 'raw ');
454 >                        WriteMacInt32(audio_data + adatData + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
455                          WriteMacInt16(audio_data + adatData + scd_numChannels, AudioStatus.channels);
456                          WriteMacInt16(audio_data + adatData + scd_sampleSize, AudioStatus.sample_size);
457                          WriteMacInt32(audio_data + adatData + scd_sampleRate, AudioStatus.sample_rate);
# Line 412 | 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 422 | 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 436 | Line 515 | delegate:      // Delegate call to Apple Mixe
515                          D(bug(" returns %08lx\n", r.d[0]));
516                          return r.d[0];
517  
439                case kSoundComponentStartSourceSelect:
440                        D(bug(" StartSource\n"));
441                        return noErr;
442
443                case kSoundComponentGetInfoSelect:
444                        return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
445
446                case kSoundComponentSetInfoSelect:
447                        return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
448
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 457 | 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 >
536 >
537 > /*
538 > *  Sound input driver Open() routine
539 > */
540 >
541 > int16 SoundInOpen(uint32 pb, uint32 dce)
542 > {
543 >        D(bug("SoundInOpen\n"));
544 >        return noErr;
545 > }
546 >
547 >
548 > /*
549 > *  Sound input driver Prime() routine
550 > */
551 >
552 > int16 SoundInPrime(uint32 pb, uint32 dce)
553 > {
554 >        D(bug("SoundInPrime\n"));
555 >        //!!
556 >        return paramErr;
557 > }
558 >
559 >
560 > /*
561 > *  Sound input driver Control() routine
562 > */
563 >
564 > int16 SoundInControl(uint32 pb, uint32 dce)
565 > {
566 >        uint16 code = ReadMacInt16(pb + csCode);
567 >        D(bug("SoundInControl %d\n", code));
568 >
569 >        if (code == 1) {
570 >                D(bug(" SoundInKillIO\n"));
571 >                //!!
572 >                return noErr;
573 >        }
574 >
575 >        if (code != 2)
576 >                return -231;    // siUnknownInfoType
577 >
578 >        uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
579 >        uint32 selector = param[0];
580 >        D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
581 >
582 >        switch (selector) {
583 >                default:
584 >                        return -231;    // siUnknownInfoType
585          }
586   }
587 +
588 +
589 + /*
590 + *  Sound input driver Status() routine
591 + */
592 +
593 + int16 SoundInStatus(uint32 pb, uint32 dce)
594 + {
595 +        uint16 code = ReadMacInt16(pb + csCode);
596 +        D(bug("SoundInStatus %d\n", code));
597 +        if (code != 2)
598 +                return -231;    // siUnknownInfoType
599 +
600 +        uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
601 +        uint32 selector = param[0];
602 +        D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
603 +        switch (selector) {
604 + #if 0
605 +                case siDeviceName: {
606 +                        const char *str = GetString(STR_SOUND_IN_NAME);
607 +                        param[0] = 0;
608 +                        memcpy((void *)param[1], str, strlen(str));
609 +                        return noErr;
610 +                }
611 +
612 +                case siDeviceIcon: {
613 +                        M68kRegisters r;
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]) {
638 +                                param[0] = 4;           // Length of returned data
639 +                                param[1] = r.a[2];      // Handle to icon suite
640 +                                return noErr;
641 +                        } else
642 +                                return -192;            // resNotFound
643 +                }
644 + #endif
645 +                default:
646 +                        return -231;    // siUnknownInfoType
647 +        }
648 + }
649 +
650 +
651 + /*
652 + *  Sound input driver Close() routine
653 + */
654 +
655 + int16 SoundInClose(uint32 pb, uint32 dce)
656 + {
657 +        D(bug("SoundInClose\n"));
658 +        return noErr;
659 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines