29 #if defined(_CARBON_) || defined(__APPLE__) 30 # if defined (__GNUC__) && (__GNUC__ >= 4) 31 # include <sys/disk.h> 33 # include <dev/disk.h> 36 #include <sys/types.h> 39 #if defined(_CARBON_) || defined(__APPLE__) 41 #include <sys/ioctl.h> 42 #include <sys/param.h> 43 #include <IOKit/IOKitLib.h> 44 #include <IOKit/IOBSD.h> 45 #include <IOKit/storage/IOMediaBSDClient.h> 46 #include <IOKit/storage/IOMedia.h> 47 #include <IOKit/storage/IOCDMedia.h> 48 #include <IOKit/storage/IOCDTypes.h> 49 #include <CoreFoundation/CoreFoundation.h> 52 #if defined(_CARBON_) || defined(__APPLE__) 64 #define MSF_TO_LBA(msf) \ 65 (((((msf).minute * 60UL) + (msf).second) * 75UL) + (msf).frame - 150) 72 struct _CDMSF address;
81 struct _CDTOC_Desc trackdesc[1];
91 static kern_return_t FindEjectableCDMedia(io_iterator_t *mediaIterator) {
92 kern_return_t kernResult;
93 CFMutableDictionaryRef classesToMatch;
96 classesToMatch = IOServiceMatching(kIOCDMediaClass);
97 if (classesToMatch == NULL) {
98 printf(
"IOServiceMatching returned a NULL dictionary.\n");
100 CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue);
105 kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, mediaIterator);
112 static kern_return_t GetBSDPath(io_iterator_t mediaIterator,
char *bsdPath, CFIndex maxPathSize) {
113 io_object_t nextMedia;
114 kern_return_t kernResult = KERN_FAILURE;
118 nextMedia = IOIteratorNext(mediaIterator);
120 CFTypeRef bsdPathAsCFString;
122 bsdPathAsCFString = IORegistryEntryCreateCFProperty(nextMedia,
123 CFSTR(kIOBSDNameKey),
126 if (bsdPathAsCFString) {
127 strlcpy(bsdPath, _PATH_DEV, maxPathSize);
133 strlcat(bsdPath,
"r", maxPathSize);
135 size_t devPathLength = strlen(bsdPath);
137 if (CFStringGetCString((CFStringRef)bsdPathAsCFString,
138 bsdPath + devPathLength,
139 maxPathSize - devPathLength,
140 kCFStringEncodingUTF8)) {
141 printf(
"BSD path: %s\n", bsdPath);
142 kernResult = KERN_SUCCESS;
145 CFRelease(bsdPathAsCFString);
148 IOObjectRelease(nextMedia);
156 static int OpenDrive(
const char *bsdPath) {
163 fileDescriptor = open(bsdPath, O_RDONLY);
165 if (fileDescriptor == -1) {
166 printf(
"Error opening device %s: ", bsdPath);
170 return fileDescriptor;
175 static Boolean ReadSector(
int fileDescriptor) {
183 if (ioctl(fileDescriptor, DKIOCGETBLOCKSIZE, &blockSize)) {
184 perror(
"Error getting preferred block size");
188 blockSize = kCDSectorSizeCDDA;
191 printf(
"Media has block size of %d bytes.\n", blockSize);
195 buffer = (
char*) malloc(blockSize);
199 numBytes = read(fileDescriptor, buffer, blockSize);
204 return numBytes == blockSize ? true :
false;
208 static void CloseDrive(
int fileDescriptor) {
209 close(fileDescriptor);
213 static struct _CDTOC * ReadTOC(
const char *devpath) {
214 struct _CDTOC * toc_p = NULL;
215 io_iterator_t iterator = 0;
216 io_registry_entry_t service = 0;
217 CFDictionaryRef properties = 0;
219 mach_port_t port = 0;
222 if ((devname = strrchr(devpath,
'/')) != NULL) {
225 devname = (
char *) devpath;
228 if (IOMasterPort(bootstrap_port, &port) != KERN_SUCCESS) {
229 fprintf(stderr,
"IOMasterPort failed\n");
233 if (IOServiceGetMatchingServices(port, IOBSDNameMatching(port, 0, devname),
234 &iterator) != KERN_SUCCESS) {
235 fprintf(stderr,
"IOServiceGetMatchingServices failed\n");
239 service = IOIteratorNext(iterator);
241 IOObjectRelease(iterator);
245 while (service && !IOObjectConformsTo(service,
"IOCDMedia")) {
246 if (IORegistryEntryGetParentIterator(service, kIOServicePlane,
247 &iterator) != KERN_SUCCESS)
249 fprintf(stderr,
"IORegistryEntryGetParentIterator failed\n");
253 IOObjectRelease(service);
254 service = IOIteratorNext(iterator);
255 IOObjectRelease(iterator);
259 fprintf(stderr,
"CD media not found\n");
263 if (IORegistryEntryCreateCFProperties(service, (__CFDictionary **) &properties,
265 kNilOptions) != KERN_SUCCESS)
267 fprintf(stderr,
"IORegistryEntryGetParentIterator failed\n");
271 data = (CFDataRef) CFDictionaryGetValue(properties, CFSTR(kIOCDMediaTOCKey));
273 fprintf(stderr,
"CFDictionaryGetValue failed\n");
279 buflen = CFDataGetLength(data) + 1;
280 range = CFRangeMake(0, buflen);
281 toc_p = (
struct _CDTOC *) malloc(buflen);
283 fprintf(stderr,
"Out of memory\n");
286 CFDataGetBytes(data, range, (
unsigned char *) toc_p);
294 CFRelease(properties);
300 IOObjectRelease(service);
306 #endif // defined(_CARBON_) || defined(__APPLE__) 315 mDirEntry = DirEntry;
324 AkaiSample::~AkaiSample()
342 mpDisk->
SetPos(mImageOffset);
361 if (!mHeaderOK)
return -1;
378 if (mPos < 0) mPos = 0;
384 if (!mHeaderOK)
return 0;
388 mpDisk->
SetPos(mImageOffset + mPos * 2);
389 mpDisk->
ReadInt16((uint16_t*)pBuffer, SampleCount);
411 mpDisk->
Read(buffer, 12, 1);
463 return (mHeaderOK =
true);
466 bool AkaiSampleLoop::Load(
DiskImage* pDisk)
486 mDirEntry = DirEntry;
491 AkaiProgram::~AkaiProgram()
494 delete[] mpKeygroups;
505 uint temppos = mpDisk->
GetPos();
510 uint8_t ProgID = mpDisk->
ReadInt8();
517 uint16_t KeygroupAddress = mpDisk->
ReadInt16();
520 mpDisk->
Read(buffer, 12, 1);
524 mMidiProgramNumber = mpDisk->
ReadInt8();
538 mAuxOutputSelect = mpDisk->
ReadInt8();
540 mMixOutputSelect = mpDisk->
ReadInt8();
546 mVelocityToVolume = mpDisk->
ReadInt8();
550 mPressureToVolume = mpDisk->
ReadInt8();
566 mModulationToLFODepth = mpDisk->
ReadInt8();
568 mPressureToLFODepth = mpDisk->
ReadInt8();
570 mVelocityToLFODepth = mpDisk->
ReadInt8();
574 mPressureToPitch = mpDisk->
ReadInt8();
576 mKeygroupCrossfade = mpDisk->
ReadInt8()?
true:
false;
578 mNumberOfKeygroups = mpDisk->
ReadInt8();
583 for (i = 0; i<11; i++)
584 mKeyTemperament[i] = mpDisk->
ReadInt8();
586 mFXOutput = mpDisk->
ReadInt8()?
true:
false;
588 mModulationToPan = mpDisk->
ReadInt8();
590 mStereoCoherence = mpDisk->
ReadInt8()?
true:
false;
592 mLFODesync = mpDisk->
ReadInt8()?
true:
false;
596 mVoiceReassign = mpDisk->
ReadInt8();
598 mSoftpedToVolume = mpDisk->
ReadInt8();
600 mSoftpedToAttack = mpDisk->
ReadInt8();
602 mSoftpedToFilter = mpDisk->
ReadInt8();
604 mSoftpedToTuneCents = mpDisk->
ReadInt8();
606 mSoftpedToTuneSemitones = mpDisk->
ReadInt8();
610 mKeyToLFODepth = mpDisk->
ReadInt8();
612 mKeyToLFODelay = mpDisk->
ReadInt8();
614 mVoiceOutputScale = mpDisk->
ReadInt8();
616 mStereoOutputScale = mpDisk->
ReadInt8();
621 delete[] mpKeygroups;
623 for (i = 0; i < mNumberOfKeygroups; i++)
627 if (!mpKeygroups[i].Load(mpDisk))
654 bool AkaiKeygroup::Load(
DiskImage* pDisk)
663 uint16_t NextKeygroupAddress = pDisk->
ReadInt16();
677 mVelocityToFilter = pDisk->
ReadInt8();
679 mPressureToFilter = pDisk->
ReadInt8();
681 mEnveloppe2ToFilter = pDisk->
ReadInt8();
700 mEnveloppes[i].Load(pDisk);
703 mVelocityToEnveloppe2ToFilter = pDisk->
ReadInt8();
705 mEnveloppe2ToPitch = pDisk->
ReadInt8();
707 mVelocityZoneCrossfade = pDisk->
ReadInt8()?
true:
false;
709 mVelocityZoneUsed = pDisk->
ReadInt8();
738 mSamples[i].Load(pDisk);
743 mHoldAttackUntilLoop = pDisk->
ReadInt8()?
true:
false;
746 mSampleKeyTracking[i] = pDisk->
ReadInt8()?
true:
false;
749 mSampleAuxOutOffset[i] = pDisk->
ReadInt8();
752 mVelocityToSampleStart[i] = pDisk->
ReadInt8();
755 mVelocityToVolumeOffset[i] = pDisk->
ReadInt8();
761 bool AkaiEnveloppe::Load(
DiskImage* pDisk)
772 mVelocityToAttack = pDisk->
ReadInt8();
774 mVelocityToRelease = pDisk->
ReadInt8();
776 mOffVelocityToRelease = pDisk->
ReadInt8();
778 mKeyToDecayAndRelease = pDisk->
ReadInt8();
782 bool AkaiKeygroupSample::Load(
DiskImage* pDisk)
786 pDisk->
Read(buffer, 12, 1);
793 uint8_t mHighLevel = pDisk->
ReadInt8();
799 int8_t mLoudness = pDisk->
ReadInt8();
826 mDirEntry = DirEntry;
830 printf(
"Creating Unknown Volume type! %d\n",mDirEntry.
mType);
832 OutputDebugString(
"Creating Unknown Volume type!\n");
837 AkaiVolume::~AkaiVolume()
840 std::list<AkaiProgram*>::iterator it;
841 std::list<AkaiProgram*>::iterator end = mpPrograms.end();
842 for (it = mpPrograms.begin(); it != end; it++)
848 std::list<AkaiSample*>::iterator it;
849 std::list<AkaiSample*>::iterator end =
mpSamples.end();
850 for (it =
mpSamples.begin(); it != end; it++)
856 uint AkaiVolume::ReadDir()
859 if (mpPrograms.empty())
862 for (i = 0; i < maxfiles; i++)
867 if (DirEntry.
mType ==
'p')
871 mpPrograms.push_back(pProgram);
873 else if (DirEntry.
mType ==
's')
881 return (uint)(mpPrograms.size() +
mpSamples.size());
889 std::list<AkaiProgram*>::iterator it;
890 std::list<AkaiProgram*>::iterator end = mpPrograms.end();
891 for (it = mpPrograms.begin(); it != end; it++)
893 rPrograms.push_back((*it)->GetDirEntry());
894 return (uint)rPrograms.size();
901 if (mpPrograms.empty())
903 std::list<AkaiDirEntry> dummy;
907 std::list<AkaiProgram*>::iterator it;
908 std::list<AkaiProgram*>::iterator end = mpPrograms.end();
909 for (it = mpPrograms.begin(); it != end; it++)
911 if (*it && i == Index)
923 if (mpPrograms.empty())
925 std::list<AkaiDirEntry> dummy;
929 std::list<AkaiProgram*>::iterator it;
930 std::list<AkaiProgram*>::iterator end = mpPrograms.end();
931 for (it = mpPrograms.begin(); it != end; it++)
933 if (*it && rName == (*it)->GetDirEntry().mName)
947 std::list<AkaiSample*>::iterator it;
948 std::list<AkaiSample*>::iterator end =
mpSamples.end();
949 for (it =
mpSamples.begin(); it != end; it++)
951 rSamples.push_back((*it)->GetDirEntry());
952 return (uint)rSamples.size();
961 std::list<AkaiDirEntry> dummy;
965 std::list<AkaiSample*>::iterator it;
966 std::list<AkaiSample*>::iterator end =
mpSamples.end();
967 for (it =
mpSamples.begin(); it != end; it++)
969 if (*it && i == Index)
983 std::list<AkaiDirEntry> dummy;
987 std::list<AkaiSample*>::iterator it;
988 std::list<AkaiSample*>::iterator end =
mpSamples.end();
989 for (it =
mpSamples.begin(); it != end; it++)
991 if (*it && rName == (*it)->GetDirEntry().mName)
1007 return ReadDir() == 0;
1019 AkaiPartition::~AkaiPartition()
1021 std::list<AkaiVolume*>::iterator it;
1022 std::list<AkaiVolume*>::iterator end = mpVolumes.end();
1023 for (it = mpVolumes.begin(); it != end; it++)
1032 if (mpVolumes.empty())
1045 mpVolumes.push_back(pVolume);
1046 rVolumes.push_back(DirEntry);
1055 std::list<AkaiVolume*>::iterator it;
1056 std::list<AkaiVolume*>::iterator end = mpVolumes.end();
1057 for (it = mpVolumes.begin(); it != end; it++)
1059 rVolumes.push_back((*it)->GetDirEntry());
1061 return (uint)rVolumes.size();
1068 if (mpVolumes.empty())
1070 std::list<AkaiDirEntry> dummy;
1074 std::list<AkaiVolume*>::iterator it;
1075 std::list<AkaiVolume*>::iterator end = mpVolumes.end();
1076 for (it = mpVolumes.begin(); it != end; it++)
1078 if (*it && i == Index)
1090 if (mpVolumes.empty())
1092 std::list<AkaiDirEntry> dummy;
1096 std::list<AkaiVolume*>::iterator it;
1097 std::list<AkaiVolume*>::iterator end = mpVolumes.end();
1098 for (it = mpVolumes.begin(); it != end; it++)
1100 if (*it && rName == (*it)->GetDirEntry().mName)
1111 std::list<AkaiDirEntry> Volumes;
1112 return ListVolumes(Volumes) == 0;
1125 std::list<AkaiPartition*>::iterator it;
1126 std::list<AkaiPartition*>::iterator end = mpPartitions.end();
1127 for (it = mpPartitions.begin(); it != end ; it++)
1134 if (!mpPartitions.empty())
1135 return (uint)mpPartitions.size();
1140 && size<30720 && mpPartitions.size()<9)
1149 mpPartitions.push_back(pPartition);
1154 return (uint)mpPartitions.size();
1160 return (uint)mpPartitions.size();
1165 std::list<AkaiPartition*>::iterator it;
1166 std::list<AkaiPartition*>::iterator end = mpPartitions.end();
1168 for (i = 0, it = mpPartitions.begin(); it != end && i != count; i++) it++;
1170 if (i != count || it == end)
1184 pDisk->
Read(&value, 2,1);
1196 pDisk->
Read(buffer, 12, 1);
1198 rEntry.
mName = buffer;
1214 temp =
ReadFAT(pDisk, pPartition, block);
1218 pDisk->
Read(buffer, 12, 1);
1220 rEntry.
mName = buffer;
1224 pDisk->
Read(&t1, 1,1);
1227 pDisk->
Read(&t1, 1,1);
1228 pDisk->
Read(&t2, 1,1);
1229 pDisk->
Read(&t3, 1,1);
1230 rEntry.
mSize = (
unsigned char)t1 | ((
unsigned char)t2 <<8) | ((
unsigned char)t3<<16);
1241 for (i = 0; i < length; i++)
1243 if (buffer[i]>=0 && buffer[i]<=9)
1245 else if (buffer[i]==10)
1247 else if (buffer[i]>=11 && buffer[i]<=36)
1248 buffer[i] = 64+(buffer[i]-10);
1252 buffer[length] =
'\0';
1253 while (length-- > 0 && buffer[length] == 32)
1257 buffer[length+1] =
'\0';
1271 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
1273 kern_return_t kernResult;
1274 mach_port_t masterPort;
1275 CFMutableDictionaryRef classesToMatch;
1277 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
1278 if ( KERN_SUCCESS != kernResult )
1280 printf(
"IOMasterPort returned %d\n", kernResult );
1283 classesToMatch = IOServiceMatching( kIOCDMediaClass );
1284 if ( classesToMatch == NULL )
1286 printf(
"IOServiceMatching returned a NULL dictionary.\n" );
1290 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
1293 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
1294 if ( KERN_SUCCESS != kernResult )
1296 printf(
"IOServiceGetMatchingServices returned %d\n", kernResult );
1302 kern_return_t GetBSDPath( io_iterator_t mediaIterator,
char *bsdPath, CFIndex maxPathSize )
1304 io_object_t nextMedia;
1305 kern_return_t kernResult = KERN_FAILURE;
1309 nextMedia = IOIteratorNext( mediaIterator );
1312 CFTypeRef bsdPathAsCFString;
1314 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia,
1315 CFSTR( kIOBSDNameKey ),
1316 kCFAllocatorDefault,
1318 if ( bsdPathAsCFString )
1320 size_t devPathLength;
1322 strcpy( bsdPath, _PATH_DEV );
1323 strcat( bsdPath,
"r" );
1325 devPathLength = strlen( bsdPath );
1327 if ( CFStringGetCString( (__CFString*)bsdPathAsCFString,
1328 bsdPath + devPathLength,
1329 maxPathSize - devPathLength,
1330 kCFStringEncodingASCII ) )
1332 printf(
"BSD path: %s\n", bsdPath );
1333 kernResult = KERN_SUCCESS;
1336 CFRelease( bsdPathAsCFString );
1338 IOObjectRelease( nextMedia );
1352 #define MSF_TO_LBA(msf) (((((msf).minute * 60UL) + (msf).second) * 75UL) + (msf).frame - 150) 1360 struct _CDMSF address;
1368 u_char first_session;
1369 u_char last_session;
1370 struct _CDTOC_Desc trackdesc[1];
1373 static struct _CDTOC * ReadTOC (
const char * devpath )
1375 struct _CDTOC * toc_p = NULL;
1376 io_iterator_t iterator = 0;
1377 io_registry_entry_t service = 0;
1378 CFDictionaryRef properties = 0;
1380 mach_port_t port = 0;
1382 if (( devname = strrchr( devpath,
'/' )) != NULL )
1388 devname = (
char *) devpath;
1391 if ( IOMasterPort(bootstrap_port, &port ) != KERN_SUCCESS )
1393 printf(
"IOMasterPort failed\n" );
goto Exit ;
1395 if ( IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, devname ),
1396 &iterator ) != KERN_SUCCESS )
1398 printf(
"IOServiceGetMatchingServices failed\n" );
goto Exit ;
1402 IOObjectGetClass(iterator,buffer);
1403 printf(
"Service: %s\n",buffer);
1406 IOIteratorReset (iterator);
1407 service = IOIteratorNext( iterator );
1409 IOObjectRelease( iterator );
1412 while ( service && !IOObjectConformsTo( service,
"IOCDMedia" ))
1415 IOObjectGetClass(service,buffer);
1416 printf(
"Service: %s\n",buffer);
1418 if ( IORegistryEntryGetParentIterator( service, kIOServicePlane, &iterator ) != KERN_SUCCESS )
1420 printf(
"IORegistryEntryGetParentIterator failed\n" );
1424 IOObjectRelease( service );
1425 service = IOIteratorNext( iterator );
1426 IOObjectRelease( iterator );
1429 if ( service == NULL )
1431 printf(
"CD media not found\n" );
goto Exit ;
1433 if ( IORegistryEntryCreateCFProperties( service, (__CFDictionary **) &properties,
1434 kCFAllocatorDefault,
1435 kNilOptions ) != KERN_SUCCESS )
1437 printf(
"IORegistryEntryGetParentIterator failed\n" );
goto Exit ;
1440 data = (CFDataRef) CFDictionaryGetValue( properties, CFSTR(
"TOC" ) );
1443 printf(
"CFDictionaryGetValue failed\n" );
goto Exit ;
1451 buflen = CFDataGetLength( data ) + 1;
1452 range = CFRangeMake( 0, buflen );
1453 toc_p = (
struct _CDTOC *) malloc( buflen );
1454 if ( toc_p == NULL )
1456 printf(
"Out of memory\n" );
goto Exit ;
1460 CFDataGetBytes( data, range, (
unsigned char *) toc_p );
1468 CFRelease( properties );
1474 IOObjectRelease( service );
1486 sprintf(buffer,
"%c:\\",
'A'+disk);
1487 mSize = GetFileSize(buffer,NULL);
1489 sprintf(buffer,
"\\\\.\\%c:",
'a'+disk);
1490 mFile = CreateFile(buffer, GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS,NULL);
1494 DISK_GEOMETRY* pdg = &dg;
1495 BOOL res = DeviceIoControl(mFile,
1496 IOCTL_DISK_GET_DRIVE_GEOMETRY,
1504 mSize = dg.BytesPerSector * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.Cylinders.LowPart;
1505 mClusterSize = dg.BytesPerSector;
1507 #elif defined(_CARBON_) || defined(__APPLE__) 1508 kern_return_t kernResult;
1509 io_iterator_t mediaIterator;
1510 char bsdPath[ MAXPATHLEN ];
1511 kernResult = FindEjectableCDMedia( &mediaIterator );
1512 kernResult = GetBSDPath( mediaIterator, bsdPath,
sizeof( bsdPath ) );
1513 if ( bsdPath[ 0 ] !=
'\0' )
1515 strcpy(bsdPath,
"/dev/rdisk1s0");
1517 struct _CDTOC * toc = ReadTOC( bsdPath );
1520 size_t toc_entries = ( toc->length - 2 ) /
sizeof (
struct _CDTOC_Desc );
1522 int start_sector = -1;
1523 int data_track = -1;
1528 for (
int i=toc_entries - 1; i>=0; i-- )
1530 if ( start_sector != -1 )
1532 start_sector = MSF_TO_LBA(toc->trackdesc[i].p) - start_sector;
1536 if (( toc->trackdesc[i].ctrl_adr >> 4) != 1 )
1538 if ( toc->trackdesc[i].ctrl_adr & 0x04 )
1540 data_track = toc->trackdesc[i].point;
1541 start_sector = MSF_TO_LBA(toc->trackdesc[i].p);
1546 if ( start_sector == -1 )
1555 mFile = open(bsdPath,O_RDONLY);
1557 printf(
"Error while opening file: %s\n",bsdPath);
1560 printf(
"opened file: %s\n",bsdPath);
1562 mSize = lseek(mFile,1000000000,SEEK_SET);
1563 printf(
"size %d\n",mSize);
1564 lseek(mFile,0,SEEK_SET);
1566 mSize = 700 * 1024 * 1024;
1570 if ( mediaIterator )
1572 IOObjectRelease( mediaIterator );
1575 OpenStream(
"/dev/cdrom");
1579 void DiskImage::Init()
1583 mCluster = (uint)-1;
1587 mpCache = (
char*) VirtualAlloc(NULL,mClusterSize,MEM_COMMIT,PAGE_READWRITE);
1596 if (mFile != INVALID_HANDLE_VALUE)
1600 #elif defined _CARBON_ || defined(__APPLE__) || LINUX 1609 VirtualFree(mpCache, 0, MEM_RELEASE);
1610 #elif defined(_CARBON_) || defined(__APPLE__) || LINUX 1655 return (mSize-mPos)/WordSize;
1661 int sizetoread = WordCount * WordSize;
1663 while (sizetoread > 0) {
1664 if (mSize <= mPos)
return readbytes / WordSize;
1665 int requestedCluster = (mRegularFile) ? mPos / mClusterSize
1666 : mPos / mClusterSize + mStartFrame;
1667 if (mCluster != requestedCluster) {
1668 mCluster = requestedCluster;
1670 if (mCluster * mClusterSize != SetFilePointer(mFile, mCluster * mClusterSize, NULL, FILE_BEGIN)) {
1671 printf(
"ERROR: couldn't seek device!\n");
1672 #if 0 // FIXME: endian correction is missing correct detection 1673 if ((readbytes > 0) && (mEndian != eEndianNative)) {
1675 case 2: bswap_16_s ((uint16*)pData, readbytes);
break;
1676 case 4: bswap_32_s ((uint32*)pData, readbytes);
break;
1677 case 8: bswap_64_s ((uint64*)pData, readbytes);
break;
1681 return readbytes / WordSize;
1684 ReadFile(mFile, mpCache, mClusterSize, &size, NULL);
1685 #elif defined(_CARBON_) || defined(__APPLE__) || LINUX 1686 if (mCluster * mClusterSize != lseek(mFile, mCluster * mClusterSize, SEEK_SET))
1687 return readbytes / WordSize;
1689 int size = read(mFile, mpCache, mClusterSize);
1695 int currentReadSize = sizetoread;
1696 int posInCluster = mPos % mClusterSize;
1697 if (currentReadSize > mClusterSize - posInCluster)
1698 currentReadSize = mClusterSize - posInCluster;
1700 memcpy((uint8_t*)pData + readbytes, mpCache + posInCluster, currentReadSize);
1702 mPos += currentReadSize;
1703 readbytes += currentReadSize;
1704 sizetoread -= currentReadSize;
1708 #if 0 // FIXME: endian correction is missing correct detection 1709 if ((readbytes > 0) && (mEndian != eEndianNative))
1712 case 2: bswap_16_s ((uint16_t*)pData, readbytes);
break;
1713 case 4: bswap_32_s ((uint32_t*)pData, readbytes);
break;
1714 case 8: bswap_64_s ((uint64_t*)pData, readbytes);
break;
1718 return readbytes / WordSize;
1722 Read(pData, WordCount, 1);
1727 for (i = 0; i < WordCount; i++) {
1728 *(pData + i) = ReadInt16();
1734 for (i = 0; i < WordCount; i++) {
1735 *(pData + i) = ReadInt32();
1740 return Read(pData, 1, 1);
1744 int result =
Read(pData, 1, 2);
1746 swapBytes_16(pData);
1752 int result =
Read(pData, 1, 4);
1754 swapBytes_32(pData);
1771 swapBytes_16(&word);
1781 swapBytes_32(&word);
1788 mFile = CreateFile(path, GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS,NULL);
1789 BY_HANDLE_FILE_INFORMATION FileInfo;
1790 GetFileInformationByHandle(mFile,&FileInfo);
1791 mSize = FileInfo.nFileSizeLow;
1792 #elif defined(_CARBON_) || defined(__APPLE__) || LINUX 1793 struct stat filestat;
1794 stat(path,&filestat);
1795 mFile = open(path, O_RDONLY | O_NONBLOCK);
1797 printf(
"Can't open %s\n", path);
1802 if (S_ISREG(filestat.st_mode)) {
1803 printf(
"Using regular Akai image file.\n");
1804 mRegularFile =
true;
1805 mSize = filestat.st_size;
1807 mpCache = (
char*) malloc(mClusterSize);
1809 #if defined(_CARBON_) || defined(__APPLE__) 1810 printf(
"Can't open %s: not a regular file\n", path);
1812 mRegularFile =
false;
1814 mpCache = (
char*) malloc(mClusterSize);
1816 struct cdrom_tochdr tochdr;
1817 struct cdrom_tocentry tocentry;
1819 if (ioctl(mFile, CDROMREADTOCHDR, (
unsigned long)&tochdr) < 0) {
1820 printf(
"Trying to read TOC of %s failed\n", path);
1825 printf(
"Total tracks: %d\n", tochdr.cdth_trk1);
1828 tocentry.cdte_format = CDROM_LBA;
1830 int firstDataTrack = -1;
1831 int start, end, length;
1834 for (
int t = tochdr.cdth_trk1; t >= 0; t--) {
1835 tocentry.cdte_track = (t == tochdr.cdth_trk1) ? CDROM_LEADOUT : t + 1;
1836 if (ioctl(mFile, CDROMREADTOCENTRY, (
unsigned long)&tocentry) < 0){
1837 printf(
"Failed to read TOC entry for track %d\n", tocentry.cdte_track);
1842 if (tocentry.cdte_track == CDROM_LEADOUT) {
1843 printf(
"Lead Out: Start(LBA)=%d\n", tocentry.cdte_addr.lba);
1846 printf(
"Track %d: Start(LBA)=%d End(LBA)=%d Length(Blocks)=%d ",
1847 tocentry.cdte_track, tocentry.cdte_addr.lba, prev_addr - 1, prev_addr - tocentry.cdte_addr.lba);
1848 if (tocentry.cdte_ctrl & CDROM_DATA_TRACK) {
1849 printf(
"Type: Data\n");
1850 firstDataTrack = tocentry.cdte_track;
1851 start = tocentry.cdte_addr.lba;
1852 end = prev_addr - 1;
1853 length = prev_addr - tocentry.cdte_addr.lba;
1855 else printf(
"Type: Audio\n");
1857 prev_addr = tocentry.cdte_addr.lba;
1860 if (firstDataTrack == -1) {
1861 printf(
"Sorry, no data track found on %s\n", path);
1867 printf(
"Ok, I'll pick track %d\n", firstDataTrack);
1868 mStartFrame = start;
1878 #if defined(_CARBON_) || defined(__APPLE__) || LINUX 1879 const uint bufferSize = 524288;
1880 int fOut = open(path, O_WRONLY | O_NONBLOCK | O_CREAT | O_TRUNC,
1881 S_IRUSR | S_IWUSR | S_IRGRP);
1883 printf(
"Can't open output file %s\n", path);
1886 uint8_t* pBuffer =
new uint8_t[bufferSize];
1888 while (Available() > 0) {
1889 int readBytes =
Read(pBuffer,bufferSize,1);
1890 if (readBytes > 0) write(fOut,pBuffer,readBytes);
1895 #endif // _CARBON_ || LINUX 1901 byteCache = *((uint8_t*) Word);
1902 *((uint8_t*) Word) = *((uint8_t*) Word + 1);
1903 *((uint8_t*) Word + 1) = byteCache;
1908 byteCache = *((uint8_t*) Word);
1909 *((uint8_t*) Word) = *((uint8_t*) Word + 3);
1910 *((uint8_t*) Word + 3) = byteCache;
1911 byteCache = *((uint8_t*) Word + 1);
1912 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
1913 *((uint8_t*) Word + 2) = byteCache;
#define AKAI_DIR_ENTRY_SIZE
AkaiPartition * GetPartition(uint count)
#define AKAI_ROOT_ENTRY_OFFSET
AkaiDirEntry GetDirEntry()
void ReadInt8(uint8_t *pData, uint WordCount)
AkaiDirEntry GetDirEntry()
bool WriteImage(const char *path)
Extract Akai data track and write it into a regular file.
virtual int Available(uint WordSize=1)
void SetOffset(uint Offset)
#define AKAI_MAX_FILE_ENTRIES_S3000
virtual int GetPos() const
#define AKAI_MAX_FILE_ENTRIES_S1000
Encapsulates one disk partition of an AKAI disk.
virtual int SetPos(int Where, akai_stream_whence_t Whence=akai_stream_start)
void swapBytes_32(void *Word)
#define AKAI_MAX_DIR_ENTRIES
#define AKAI_DIR_ENTRY_OFFSET
DiskImage(const char *path)
Open an image from a file.
uint ListPrograms(std::list< AkaiDirEntry > &rPrograms)
#define AKAI_FILE_ENTRY_SIZE
Toplevel AKAI image interpreter.
void ReadInt32(uint32_t *pData, uint WordCount)
AkaiVolume * GetVolume(uint Index)
void OpenStream(const char *path)
int ReadFAT(DiskImage *pDisk, AkaiPartition *pPartition, int block)
AkaiSample * GetSample(uint Index)
void ReadInt16(uint16_t *pData, uint WordCount)
#define DISK_CLUSTER_SIZE
uint16_t mSamplingFrequency
bool LoadSampleData()
Load sample into RAM.
int Read(void *pBuffer, uint SampleCount)
Use this method and SetPos() if you don't want to load the sample into RAM, thus for disk streaming...
#define AKAI_PARTITION_END_MARK
Accessing AKAI image either from file or a drive (i.e.
uint ListSamples(std::list< AkaiDirEntry > &rSamples)
AkaiDirEntry GetDirEntry()
void AkaiToAscii(char *buffer, int length)
uint ListSamples(std::list< String > &rSamples)
AkaiProgram * GetProgram(uint Index)
AkaiDiskElement(uint Offset=0)
AKAI instrument definition.
int SetPos(int Where, akai_stream_whence_t Whence=akai_stream_start)
Use this method and Read() if you don't want to load the sample into RAM, thus for disk streaming...
AkaiDisk(DiskImage *pDisk)
#define AKAI_TYPE_DIR_S3000
void ReleaseSampleData()
release the samples once you used them if you don't want to be bothered to
Subdivision of an AKAI disk partition.
uint32_t mNumberOfSamples
AkaiSample * GetSample(uint Index)
AkaiPartition * GetParent()
virtual int Read(void *pData, uint WordCount, uint WordSize)
Returns number of successfully read words.
#define AKAI_TYPE_DIR_S1000
bool ReadDirEntry(DiskImage *pDisk, AkaiPartition *pPartition, AkaiDirEntry &rEntry, int block, int pos)
virtual akai_stream_state_t GetState() const
uint ListVolumes(std::list< AkaiDirEntry > &rVolumes)
void swapBytes_16(void *Word)