From d853f9abae41f828ea9e5a6f5d17f23ad5a62c61 Mon Sep 17 00:00:00 2001 From: Seth Polsley Date: Tue, 18 Aug 2020 14:47:03 -0500 Subject: [PATCH 1/5] Restoring driver patch for sound id -16501 for New World ROMs --- SheepShaver/src/rsrc_patches.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SheepShaver/src/rsrc_patches.cpp b/SheepShaver/src/rsrc_patches.cpp index ccd1c33d..23b1b9b4 100644 --- a/SheepShaver/src/rsrc_patches.cpp +++ b/SheepShaver/src/rsrc_patches.cpp @@ -517,13 +517,11 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size) D(bug(" patch applied\n")); } - // patch for -16501 resource ID not even needed? seems to run off native driver without -/* } else if (type == FOURCC('D','R','V','R') && (id == -16501)){// || id == -16500)) { // -16500 will patch over native driver and traps out to code, but very hard to re-implement there! + } else if (type == FOURCC('D','R','V','R') && (id == -16501)){// || id == -16500)) { // -16500 will patch over native sound input driver and traps out to code in audio.cpp D(bug("DRVR -16501/-16500 found\n")); // Install sound input driver memcpy(p, sound_input_driver, sizeof(sound_input_driver)); D(bug(" patch 1 applied\n")); -*/ } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) { D(bug("INIT 1 (size 2416) found\n")); size >>= 1; From 177555e0d17918b558d3b0d59591b8efcb35379e Mon Sep 17 00:00:00 2001 From: Seth Polsley Date: Thu, 10 Sep 2020 00:51:24 -0500 Subject: [PATCH 2/5] Loading soundin patch with resources writing to ROM --- BasiliskII/src/audio.cpp | 163 +++++++++++++++++++++++----- BasiliskII/src/include/audio.h | 3 + BasiliskII/src/include/audio_defs.h | 1 + SheepShaver/src/rsrc_patches.cpp | 38 ++++++- 4 files changed, 175 insertions(+), 30 deletions(-) diff --git a/BasiliskII/src/audio.cpp b/BasiliskII/src/audio.cpp index 6a52a0ef..261616d1 100644 --- a/BasiliskII/src/audio.cpp +++ b/BasiliskII/src/audio.cpp @@ -33,6 +33,7 @@ #include "audio_defs.h" #include "user_strings.h" #include "cdrom.h" +#include "vm_alloc.h" #define DEBUG 0 #include "debug.h" @@ -53,6 +54,11 @@ static int open_count = 0; // Open/close nesting count bool AudioAvailable = false; // Flag: audio output available (from the software point of view) +uint32 SoundInNameAddr; +uint32 SoundInSourcesAddr; +int SoundInSource = 2; +int SoundInPlaythrough = 7; +int SoundInGain = 65536; // FIXED 4-byte from 0.5 to 1.5; this is middle value (1) as int /* * Reset audio emulation @@ -603,6 +609,25 @@ int16 SoundInControl(uint32 pb, uint32 dce) return noErr; } + case siInputSource: { + SoundInSource = ReadMacInt16(pb + csParam + 4); + return noErr; + } + + case siPlayThruOnOff: { + SoundInPlaythrough = ReadMacInt16(pb + csParam + 4); + return noErr; + } + + case siOptionsDialog: { + return noErr; + } + + case siInputGain: { + SoundInGain = ReadMacInt32(pb + csParam + 4); + return noErr; + } + default: return -231; // siUnknownInfoType } @@ -636,9 +661,34 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame 0x74, 0x2d, // t- 0x69, 0x6e // in }; +// const uint8 str[] = { // size 12 +// 0x0b, // 1-byte length +// 0x53, 0x68, // Sh +// 0x65, 0x65, // ee +// 0x70, 0x73, // ps +// 0x68, 0x61, // ha +// 0x76, 0x65, // ve +// 0x72 // r +// }; WriteMacInt32(pb + csParam, 0); // response will directly be written into buffer // vm_memcpy(bufferptr, str, 9); - memcpy(Mac2HostAddr(bufferptr),str,9); +// memcpy(Mac2HostAddr(bufferptr),str,9); + + vm_memcpy(bufferptr, str, sizeof(str)); +// memcpy(Mac2HostAddr(bufferptr),str,sizeof(str)); + +// WriteMacInt32(pb + csParam, sizeof(str)); +// uint8* virtual_addr = (uint8*) vm_acquire(sizeof(str)); +// memcpy((uint8*) virtual_addr, str, sizeof(str)); +// WriteMacInt32(bufferptr, Host2MacAddr(virtual_addr)); +// WriteMacInt32(ReadMacInt32(bufferptr), SoundInNameAddr); + +// vm_memcpy(bufferptr, SoundInNameAddr, 12); + +// uint32 virtual_addr = Mac_sysalloc(sizeof(str)); +// Host2Mac_memcpy(virtual_addr, str, sizeof(str)); +// WriteMacInt32(bufferptr, virtual_addr); + return noErr; } @@ -646,6 +696,7 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame // Borrow ICN resource from cd rom driver, just a hack since loading a true ICN would be better WriteMacInt32(pb + csParam, 0); WriteMacInt32(bufferptr, CDROMIconAddr); +// vm_memcpy(bufferptr, CDROMIconAddr, sizeof(CDROMIcon)); return noErr; // 68k code causes crash in sheep and link error in basilisk @@ -683,52 +734,108 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame case siInputSource: { // return -231 if only 1 or index if more - return -231; +// return -231; -// WriteMacInt32(pb + csParam, 4); -// WriteMacInt32(pb + csParam + 4, 1); // index 1 -// return noErr; + WriteMacInt32(pb + csParam, 2); + WriteMacInt16(pb + csParam + 4, SoundInSource); // index of selected source + return noErr; } case siInputSourceNames: { // list of sources in STR# resource format // return -231 if only 1 or handle to STR# resource if more - return -231; +// return -231; -// const uint8 str[] = { -// 0x00, 0x02, // 2-byte count of #strings -// 0x0b, // byte size indicator (up to 255 length supported) -// 0x49, 0x6e, // start of string in ASCII, In -// 0x74, 0x65, // te -// 0x72, 0x6e, // rn -// 0x61, 0x6c, // al -// 0x20, 0x43, // C -// 0x44, // D -// 0x0a, // size is 10 -// 0x4d, 0x69, // Mi -// 0x63, 0x72, // cr -// 0x6f, 0x70, // op -// 0x68, 0x6f, // ho -// 0x6e, 0x65, // ne -// }; + const uint8 str[] = { + 0x00, 0x02, // 2-byte count of #strings + 0x0a, // byte size indicator (up to 255 length supported) + 0x4d, 0x69, // Mi + 0x63, 0x72, // cr + 0x6f, 0x70, // op + 0x68, 0x6f, // ho + 0x6e, 0x65, // ne + 0x0b, // size is 11 + 0x49, 0x6e, // start of string in ASCII, In + 0x74, 0x65, // te + 0x72, 0x6e, // rn + 0x61, 0x6c, // al + 0x20, 0x43, // C + 0x44, // D + }; // -// WriteMacInt32(pb + csParam, 0); + WriteMacInt32(pb + csParam, 0); // vm_memcpy(bufferptr, str, 25); -// return noErr; + +// vm_memcpy(bufferptr, SoundInSourcesAddr, sizeof(str)); +// WriteMacInt32(bufferptr, SoundInSourcesAddr); + +// WriteMacInt32(ReadMacInt32(bufferptr),SoundInSourcesAddr); + + M68kRegisters r; +// r.d[0] = audio_channel_counts.size() * 2; + r.d[0] = sizeof(str); + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; +// WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size()); + WriteMacInt32(bufferptr, h); + uint32 sp = ReadMacInt32(h); + vm_memcpy(sp, str, sizeof(str)); +// for (unsigned i=0; i> 8, M68K_EMUL_OP_SOUNDIN_CLOSE & 0xff, 0x4e, 0x75, // rts }; +static const uint8 sound_input_resources[] = { + // DRVR resources + // Name + 0x0b, // 1-byte length + 0x53, 0x68, // Sh + 0x65, 0x65, // ee + 0x70, 0x73, // ps + 0x68, 0x61, // ha + 0x76, 0x65, // ve + 0x72, // r + + // Source list + 0x00, 0x02, // 2-byte count of #strings + 0x0b, // byte size indicator (up to 255 length supported) + 0x49, 0x6e, // start of string in ASCII, In + 0x74, 0x65, // te + 0x72, 0x6e, // rn + 0x61, 0x6c, // al + 0x20, 0x43, // C + 0x44, // D + 0x0a, // size is 10 + 0x4d, 0x69, // Mi + 0x63, 0x72, // cr + 0x6f, 0x70, // op + 0x68, 0x6f, // ho + 0x6e, 0x65, // ne +}; +bool audio_patched = false; /* * Search resource for byte string, return offset (or 0) @@ -517,10 +545,16 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size) D(bug(" patch applied\n")); } - } else if (type == FOURCC('D','R','V','R') && (id == -16501)){// || id == -16500)) { // -16500 will patch over native sound input driver and traps out to code in audio.cpp + } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) { // -16500 will patch over native sound input driver and traps out to code in audio.cpp D(bug("DRVR -16501/-16500 found\n")); // Install sound input driver - memcpy(p, sound_input_driver, sizeof(sound_input_driver)); + vm_memcpy(Host2MacAddr((uint8 *) p), sound_input_driver, sizeof(sound_input_driver)); + vm_memcpy(Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver), sound_input_resources, sizeof(sound_input_resources)); + if (!audio_patched) { + SoundInNameAddr = Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver); + SoundInSourcesAddr = Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver) + 12; + audio_patched = true; + } D(bug(" patch 1 applied\n")); } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) { D(bug("INIT 1 (size 2416) found\n")); From 2a904af8e703611c6846b790f6b967ab5a720275 Mon Sep 17 00:00:00 2001 From: Seth Polsley Date: Thu, 10 Sep 2020 01:36:49 -0500 Subject: [PATCH 3/5] Cleaner soundin driver implementation --- BasiliskII/src/audio.cpp | 83 ++++++++++------------------- BasiliskII/src/include/audio.h | 3 -- BasiliskII/src/include/audio_defs.h | 2 +- SheepShaver/src/rsrc_patches.cpp | 37 +------------ 4 files changed, 30 insertions(+), 95 deletions(-) diff --git a/BasiliskII/src/audio.cpp b/BasiliskII/src/audio.cpp index 261616d1..9485d75f 100644 --- a/BasiliskII/src/audio.cpp +++ b/BasiliskII/src/audio.cpp @@ -33,7 +33,6 @@ #include "audio_defs.h" #include "user_strings.h" #include "cdrom.h" -#include "vm_alloc.h" #define DEBUG 0 #include "debug.h" @@ -54,8 +53,6 @@ static int open_count = 0; // Open/close nesting count bool AudioAvailable = false; // Flag: audio output available (from the software point of view) -uint32 SoundInNameAddr; -uint32 SoundInSourcesAddr; int SoundInSource = 2; int SoundInPlaythrough = 7; int SoundInGain = 65536; // FIXED 4-byte from 0.5 to 1.5; this is middle value (1) as int @@ -647,12 +644,11 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame // two choices on return // 1: if under 18 bytes, place # of bytes at (pb+csParam) and write from (pb+csParam+4) on - // 2: if over 18 bytes, place 0 at (pb+csParam) and directly write into buffer pointed to by bufferptr + // 2: if over 18 bytes, place 0 at (pb+csParam) and directly write into address pointed to by (pb+csParam+4) uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above) uint32 bufferptr = ReadMacInt32(pb + csParam + 4); // 4-byte address to the buffer in vm memory switch (selector) { -//#if 0 case siDeviceName: { // return name in STR255 format const uint8 str[] = { // size 9 0x08, // 1-byte length @@ -662,7 +658,7 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame 0x69, 0x6e // in }; // const uint8 str[] = { // size 12 -// 0x0b, // 1-byte length +// 0x0b, // 1-byte length // 0x53, 0x68, // Sh // 0x65, 0x65, // ee // 0x70, 0x73, // ps @@ -670,33 +666,26 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame // 0x76, 0x65, // ve // 0x72 // r // }; - WriteMacInt32(pb + csParam, 0); // response will directly be written into buffer -// vm_memcpy(bufferptr, str, 9); -// memcpy(Mac2HostAddr(bufferptr),str,9); - + WriteMacInt32(pb + csParam, 0); // response will be written directly into buffer vm_memcpy(bufferptr, str, sizeof(str)); -// memcpy(Mac2HostAddr(bufferptr),str,sizeof(str)); - -// WriteMacInt32(pb + csParam, sizeof(str)); -// uint8* virtual_addr = (uint8*) vm_acquire(sizeof(str)); -// memcpy((uint8*) virtual_addr, str, sizeof(str)); -// WriteMacInt32(bufferptr, Host2MacAddr(virtual_addr)); -// WriteMacInt32(ReadMacInt32(bufferptr), SoundInNameAddr); - -// vm_memcpy(bufferptr, SoundInNameAddr, 12); - -// uint32 virtual_addr = Mac_sysalloc(sizeof(str)); -// Host2Mac_memcpy(virtual_addr, str, sizeof(str)); -// WriteMacInt32(bufferptr, virtual_addr); return noErr; } case siDeviceIcon: { - // Borrow ICN resource from cd rom driver, just a hack since loading a true ICN would be better + // todo: add soundin ICN, borrow from CD ROM for now WriteMacInt32(pb + csParam, 0); - WriteMacInt32(bufferptr, CDROMIconAddr); -// vm_memcpy(bufferptr, CDROMIconAddr, sizeof(CDROMIcon)); + + M68kRegisters r; + r.d[0] = sizeof(CDROMIcon); + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; + WriteMacInt32(bufferptr, h); + uint32 sp = ReadMacInt32(h); + vm_memcpy(sp, CDROMIcon, sizeof(CDROMIcon)); + return noErr; // 68k code causes crash in sheep and link error in basilisk @@ -733,21 +722,20 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame } case siInputSource: { - // return -231 if only 1 or index if more -// return -231; - + // return -231 if only 1 or index of current source if more + WriteMacInt32(pb + csParam, 2); WriteMacInt16(pb + csParam + 4, SoundInSource); // index of selected source return noErr; } - case siInputSourceNames: { // list of sources in STR# resource format + case siInputSourceNames: { // return -231 if only 1 or handle to STR# resource if more -// return -231; const uint8 str[] = { 0x00, 0x02, // 2-byte count of #strings - 0x0a, // byte size indicator (up to 255 length supported) + // byte size indicator (up to 255 length supported) + 0x0a, // size is 10 0x4d, 0x69, // Mi 0x63, 0x72, // cr 0x6f, 0x70, // op @@ -761,36 +749,26 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame 0x20, 0x43, // C 0x44, // D }; -// + WriteMacInt32(pb + csParam, 0); -// vm_memcpy(bufferptr, str, 25); - -// vm_memcpy(bufferptr, SoundInSourcesAddr, sizeof(str)); -// WriteMacInt32(bufferptr, SoundInSourcesAddr); - -// WriteMacInt32(ReadMacInt32(bufferptr),SoundInSourcesAddr); - + M68kRegisters r; -// r.d[0] = audio_channel_counts.size() * 2; r.d[0] = sizeof(str); Execute68kTrap(0xa122, &r); // NewHandle() uint32 h = r.a[0]; if (h == 0) return memFullErr; -// WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size()); WriteMacInt32(bufferptr, h); uint32 sp = ReadMacInt32(h); vm_memcpy(sp, str, sizeof(str)); -// for (unsigned i=0; i> 8, M68K_EMUL_OP_SOUNDIN_CLOSE & 0xff, 0x4e, 0x75, // rts }; -static const uint8 sound_input_resources[] = { - // DRVR resources - // Name - 0x0b, // 1-byte length - 0x53, 0x68, // Sh - 0x65, 0x65, // ee - 0x70, 0x73, // ps - 0x68, 0x61, // ha - 0x76, 0x65, // ve - 0x72, // r - - // Source list - 0x00, 0x02, // 2-byte count of #strings - 0x0b, // byte size indicator (up to 255 length supported) - 0x49, 0x6e, // start of string in ASCII, In - 0x74, 0x65, // te - 0x72, 0x6e, // rn - 0x61, 0x6c, // al - 0x20, 0x43, // C - 0x44, // D - 0x0a, // size is 10 - 0x4d, 0x69, // Mi - 0x63, 0x72, // cr - 0x6f, 0x70, // op - 0x68, 0x6f, // ho - 0x6e, 0x65, // ne - -}; -bool audio_patched = false; /* * Search resource for byte string, return offset (or 0) @@ -545,16 +516,10 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size) D(bug(" patch applied\n")); } - } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) { // -16500 will patch over native sound input driver and traps out to code in audio.cpp + } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) { // patch over native sound input driver and trap out to code in audio.cpp D(bug("DRVR -16501/-16500 found\n")); // Install sound input driver vm_memcpy(Host2MacAddr((uint8 *) p), sound_input_driver, sizeof(sound_input_driver)); - vm_memcpy(Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver), sound_input_resources, sizeof(sound_input_resources)); - if (!audio_patched) { - SoundInNameAddr = Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver); - SoundInSourcesAddr = Host2MacAddr((uint8 *) p) + sizeof(sound_input_driver) + 12; - audio_patched = true; - } D(bug(" patch 1 applied\n")); } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) { D(bug("INIT 1 (size 2416) found\n")); From 40e2d3d84b4179b9ce2ffbac8a0201a519e6047c Mon Sep 17 00:00:00 2001 From: Seth Polsley Date: Thu, 10 Sep 2020 17:31:21 -0500 Subject: [PATCH 4/5] Removing temp ignoresegv patch --- SheepShaver/src/include/rom_patches.h | 1 - SheepShaver/src/rom_patches.cpp | 3 --- SheepShaver/src/rsrc_patches.cpp | 1 - 3 files changed, 5 deletions(-) diff --git a/SheepShaver/src/include/rom_patches.h b/SheepShaver/src/include/rom_patches.h index a4b4e283..c263606a 100644 --- a/SheepShaver/src/include/rom_patches.h +++ b/SheepShaver/src/include/rom_patches.h @@ -31,7 +31,6 @@ enum { ROMTYPE_NEWWORLD }; extern int ROMType; -extern bool SoundPatchFlag; extern bool DecodeROM(uint8 *data, uint32 size); extern bool PatchROM(void); diff --git a/SheepShaver/src/rom_patches.cpp b/SheepShaver/src/rom_patches.cpp index 804d6a97..b9ccc986 100644 --- a/SheepShaver/src/rom_patches.cpp +++ b/SheepShaver/src/rom_patches.cpp @@ -67,7 +67,6 @@ const uint32 ADDR_MAP_PATCH_SPACE = 0x2fd140; // Global variables int ROMType; // ROM type -bool SoundPatchFlag; static uint32 sony_offset; // Offset of .Sony driver resource // Prototypes @@ -694,8 +693,6 @@ bool PatchROM(void) ROMType = ROMTYPE_NEWWORLD; else return false; - - SoundPatchFlag = ROMType == ROMTYPE_NEWWORLD && !PrefsFindBool("ignoresegv"); // Check that other ROM addresses point to really free regions if (!check_rom_patch_space(CHECK_LOAD_PATCH_SPACE, 0x40)) diff --git a/SheepShaver/src/rsrc_patches.cpp b/SheepShaver/src/rsrc_patches.cpp index 06ab27b8..344b1bad 100644 --- a/SheepShaver/src/rsrc_patches.cpp +++ b/SheepShaver/src/rsrc_patches.cpp @@ -522,7 +522,6 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size) // Install sound input driver memcpy(p, sound_input_driver, sizeof(sound_input_driver)); D(bug(" patch 1 applied\n")); -*/ } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) { D(bug("INIT 1 (size 2416) found\n")); size >>= 1; From 25e2d4af6f9ebe24bb8476d2444078ef23ee74b9 Mon Sep 17 00:00:00 2001 From: Seth Polsley Date: Fri, 11 Sep 2020 14:44:58 -0500 Subject: [PATCH 5/5] Removing vm_memcpy dependency for BII --- BasiliskII/src/audio.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/BasiliskII/src/audio.cpp b/BasiliskII/src/audio.cpp index 9485d75f..fa861f28 100644 --- a/BasiliskII/src/audio.cpp +++ b/BasiliskII/src/audio.cpp @@ -667,7 +667,7 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame // 0x72 // r // }; WriteMacInt32(pb + csParam, 0); // response will be written directly into buffer - vm_memcpy(bufferptr, str, sizeof(str)); + Host2Mac_memcpy(bufferptr, str, sizeof(str)); return noErr; } @@ -684,7 +684,7 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame return memFullErr; WriteMacInt32(bufferptr, h); uint32 sp = ReadMacInt32(h); - vm_memcpy(sp, CDROMIcon, sizeof(CDROMIcon)); + Host2Mac_memcpy(sp, CDROMIcon, sizeof(CDROMIcon)); return noErr; @@ -760,7 +760,7 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame return memFullErr; WriteMacInt32(bufferptr, h); uint32 sp = ReadMacInt32(h); - vm_memcpy(sp, str, sizeof(str)); + Host2Mac_memcpy(sp, str, sizeof(str)); return noErr; } @@ -794,12 +794,18 @@ int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parame case siSampleRateAvailable: { WriteMacInt32(pb + csParam, 0); + + M68kRegisters r; + r.d[0] = 4; + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; + WriteMacInt16(bufferptr, 1); // 1 sample rate available + WriteMacInt32(bufferptr + 2, h); // handle to sample rate list + uint32 sp = ReadMacInt32(h); + WriteMacInt32(sp, 0xac440000); // 44100.00000 Hz, of Fixed data type - uint32 virtual_addr = Mac_sysalloc(4); - WriteMacInt32(virtual_addr, 0xac440000); // 44100.00000 Hz, of Fixed data type - - WriteMacInt16(bufferptr, 1); // 1 sample rate available - WriteMacInt32(bufferptr + 2, virtual_addr); // handle to the sample rate list return noErr; }