mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added CDDB support for mac. Small fix for iPad text entry.
This commit is contained in:
parent
1335673bf0
commit
cd14d5efa5
21 changed files with 428 additions and 358 deletions
|
|
@ -45,6 +45,7 @@ OBJECTS := \
|
|||
$(OBJDIR)/juce_ApplicationCommandTarget_90a89aa9.o \
|
||||
$(OBJDIR)/juce_ApplicationProperties_a76b5c30.o \
|
||||
$(OBJDIR)/juce_AiffAudioFormat_ffbda971.o \
|
||||
$(OBJDIR)/juce_AudioCDReader_c730f7a6.o \
|
||||
$(OBJDIR)/juce_AudioFormat_6605d0f9.o \
|
||||
$(OBJDIR)/juce_AudioFormatManager_949148fe.o \
|
||||
$(OBJDIR)/juce_AudioSubsectionReader_65f61a0a.o \
|
||||
|
|
@ -385,6 +386,11 @@ $(OBJDIR)/juce_AiffAudioFormat_ffbda971.o: ../../src/audio/audio_file_formats/ju
|
|||
@echo "Compiling juce_AiffAudioFormat.cpp"
|
||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
|
||||
|
||||
$(OBJDIR)/juce_AudioCDReader_c730f7a6.o: ../../src/audio/audio_file_formats/juce_AudioCDReader.cpp
|
||||
-@mkdir -p $(OBJDIR)
|
||||
@echo "Compiling juce_AudioCDReader.cpp"
|
||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
|
||||
|
||||
$(OBJDIR)/juce_AudioFormat_6605d0f9.o: ../../src/audio/audio_file_formats/juce_AudioFormat.cpp
|
||||
-@mkdir -p $(OBJDIR)
|
||||
@echo "Compiling juce_AudioFormat.cpp"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
CD59C8E60146B04575CD61E6 = { isa = PBXBuildFile; fileRef = 415BD77DF4B2F4760D138735; };
|
||||
76890501626BFFF310A94F15 = { isa = PBXBuildFile; fileRef = BA97FEDA576503A21D971F1E; };
|
||||
46151070FA7D3426EC35280F = { isa = PBXBuildFile; fileRef = 1AA8BE2D76E153874FB08197; };
|
||||
983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; };
|
||||
416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; };
|
||||
9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; };
|
||||
FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; };
|
||||
|
|
@ -349,6 +350,7 @@
|
|||
1AA8BE2D76E153874FB08197 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AiffAudioFormat.cpp; path = ../../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp; sourceTree = SOURCE_ROOT; };
|
||||
05C5C546E12C6422D865D864 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AiffAudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AiffAudioFormat.h; sourceTree = SOURCE_ROOT; };
|
||||
1F5A667524FB005D872340E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioCDBurner.h; path = ../../src/audio/audio_file_formats/juce_AudioCDBurner.h; sourceTree = SOURCE_ROOT; };
|
||||
0877D5750D6F21C5231687CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioCDReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioCDReader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
1BBE03BB0D71FEEEA440682B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioCDReader.h; path = ../../src/audio/audio_file_formats/juce_AudioCDReader.h; sourceTree = SOURCE_ROOT; };
|
||||
7D85530D76756C33795ECCE9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormat.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormat.cpp; sourceTree = SOURCE_ROOT; };
|
||||
013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -1033,6 +1035,7 @@
|
|||
1AA8BE2D76E153874FB08197,
|
||||
05C5C546E12C6422D865D864,
|
||||
1F5A667524FB005D872340E1,
|
||||
0877D5750D6F21C5231687CA,
|
||||
1BBE03BB0D71FEEEA440682B,
|
||||
7D85530D76756C33795ECCE9,
|
||||
013E8938EE1C6B4F63016B55,
|
||||
|
|
@ -1898,6 +1901,7 @@
|
|||
CD59C8E60146B04575CD61E6,
|
||||
76890501626BFFF310A94F15,
|
||||
46151070FA7D3426EC35280F,
|
||||
983FCD60625A60993546F850,
|
||||
416D6F00E88DC74879B4DF2B,
|
||||
9C709BC2F4F0EE60BF52FACA,
|
||||
FB21B7E6A7CE55D3C0E3C37E,
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@
|
|||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDBurner.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@
|
|||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDBurner.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@
|
|||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDBurner.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioCDReader.h"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/>
|
||||
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@
|
|||
<ClCompile Include="..\..\src\application\juce_ApplicationCommandTarget.cpp"/>
|
||||
<ClCompile Include="..\..\src\application\juce_ApplicationProperties.cpp"/>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.cpp"/>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/>
|
||||
|
|
|
|||
|
|
@ -193,6 +193,9 @@
|
|||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AiffAudioFormat.cpp">
|
||||
<Filter>Juce\Source\audio\audio_file_formats</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp">
|
||||
<Filter>Juce\Source\audio\audio_file_formats</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp">
|
||||
<Filter>Juce\Source\audio\audio_file_formats</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
CD59C8E60146B04575CD61E6 = { isa = PBXBuildFile; fileRef = 415BD77DF4B2F4760D138735; };
|
||||
76890501626BFFF310A94F15 = { isa = PBXBuildFile; fileRef = BA97FEDA576503A21D971F1E; };
|
||||
46151070FA7D3426EC35280F = { isa = PBXBuildFile; fileRef = 1AA8BE2D76E153874FB08197; };
|
||||
983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; };
|
||||
416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; };
|
||||
9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; };
|
||||
FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; };
|
||||
|
|
@ -349,6 +350,7 @@
|
|||
1AA8BE2D76E153874FB08197 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AiffAudioFormat.cpp; path = ../../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp; sourceTree = SOURCE_ROOT; };
|
||||
05C5C546E12C6422D865D864 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AiffAudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AiffAudioFormat.h; sourceTree = SOURCE_ROOT; };
|
||||
1F5A667524FB005D872340E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioCDBurner.h; path = ../../src/audio/audio_file_formats/juce_AudioCDBurner.h; sourceTree = SOURCE_ROOT; };
|
||||
0877D5750D6F21C5231687CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioCDReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioCDReader.cpp; sourceTree = SOURCE_ROOT; };
|
||||
1BBE03BB0D71FEEEA440682B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioCDReader.h; path = ../../src/audio/audio_file_formats/juce_AudioCDReader.h; sourceTree = SOURCE_ROOT; };
|
||||
7D85530D76756C33795ECCE9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormat.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormat.cpp; sourceTree = SOURCE_ROOT; };
|
||||
013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -1033,6 +1035,7 @@
|
|||
1AA8BE2D76E153874FB08197,
|
||||
05C5C546E12C6422D865D864,
|
||||
1F5A667524FB005D872340E1,
|
||||
0877D5750D6F21C5231687CA,
|
||||
1BBE03BB0D71FEEEA440682B,
|
||||
7D85530D76756C33795ECCE9,
|
||||
013E8938EE1C6B4F63016B55,
|
||||
|
|
@ -1898,6 +1901,7 @@
|
|||
CD59C8E60146B04575CD61E6,
|
||||
76890501626BFFF310A94F15,
|
||||
46151070FA7D3426EC35280F,
|
||||
983FCD60625A60993546F850,
|
||||
416D6F00E88DC74879B4DF2B,
|
||||
9C709BC2F4F0EE60BF52FACA,
|
||||
FB21B7E6A7CE55D3C0E3C37E,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@
|
|||
file="src/audio/audio_file_formats/juce_AiffAudioFormat.h"/>
|
||||
<FILE id="iaSLTdAgX" name="juce_AudioCDBurner.h" compile="0" resource="0"
|
||||
file="src/audio/audio_file_formats/juce_AudioCDBurner.h"/>
|
||||
<FILE id="0iwk53E" name="juce_AudioCDReader.cpp" compile="1" resource="0"
|
||||
file="src/audio/audio_file_formats/juce_AudioCDReader.cpp"/>
|
||||
<FILE id="RV1XmJohc" name="juce_AudioCDReader.h" compile="0" resource="0"
|
||||
file="src/audio/audio_file_formats/juce_AudioCDReader.h"/>
|
||||
<FILE id="7bdvMw9hr" name="juce_AudioFormat.cpp" compile="1" resource="0"
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@
|
|||
#include "../src/audio/audio_file_formats/juce_AudioThumbnailCache.cpp"
|
||||
#include "../src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp"
|
||||
#include "../src/audio/audio_file_formats/juce_WavAudioFormat.cpp"
|
||||
#include "../src/audio/audio_file_formats/juce_AudioCDReader.cpp"
|
||||
#include "../src/audio/audio_sources/juce_AudioFormatReaderSource.cpp"
|
||||
#include "../src/audio/audio_sources/juce_AudioSourcePlayer.cpp"
|
||||
#include "../src/audio/audio_sources/juce_AudioTransportSource.cpp"
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@
|
|||
reduce code size.
|
||||
*/
|
||||
#ifndef JUCE_USE_CDREADER
|
||||
#define JUCE_USE_CDREADER 0
|
||||
#define JUCE_USE_CDREADER 1
|
||||
#endif
|
||||
|
||||
/** JUCE_USE_CAMERA: Enables web-cam support using the CameraDevice class (Mac and Windows).
|
||||
|
|
@ -22470,6 +22470,47 @@ END_JUCE_NAMESPACE
|
|||
/*** End of inlined file: juce_WavAudioFormat.cpp ***/
|
||||
|
||||
|
||||
/*** Start of inlined file: juce_AudioCDReader.cpp ***/
|
||||
#if JUCE_USE_CDREADER
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return trackStartSamples.size() - 1;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return trackStartSamples [trackNum];
|
||||
}
|
||||
|
||||
const Array<int>& AudioCDReader::getTrackOffsets() const
|
||||
{
|
||||
return trackStartSamples;
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
int checksum = 0;
|
||||
const int numTracks = getNumTracks();
|
||||
|
||||
for (int i = 0; i < numTracks; ++i)
|
||||
for (int offset = (trackStartSamples.getUnchecked(i) + 88200) / 44100; offset > 0; offset /= 10)
|
||||
checksum += offset % 10;
|
||||
|
||||
const int length = (trackStartSamples.getLast() - trackStartSamples.getFirst()) / 44100;
|
||||
|
||||
// CCLLLLTT: checksum, length, tracks
|
||||
return ((checksum & 0xff) << 24) | (length << 8) | numTracks;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
/*** End of inlined file: juce_AudioCDReader.cpp ***/
|
||||
|
||||
|
||||
/*** Start of inlined file: juce_AudioFormatReaderSource.cpp ***/
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
|
@ -245023,7 +245064,7 @@ public:
|
|||
CloseHandle (scsiHandle);
|
||||
}
|
||||
|
||||
bool readTOC (TOC* lpToc, bool useMSF);
|
||||
bool readTOC (TOC* lpToc);
|
||||
bool readAudio (CDReadBuffer* buffer, CDReadBuffer* overlapBuffer = 0);
|
||||
void openDrawer (bool shouldBeOpen);
|
||||
|
||||
|
|
@ -245581,7 +245622,7 @@ int CDController::getLastIndex()
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool CDDeviceHandle::readTOC (TOC* lpToc, bool useMSF)
|
||||
bool CDDeviceHandle::readTOC (TOC* lpToc)
|
||||
{
|
||||
HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
|
||||
|
||||
|
|
@ -245599,7 +245640,7 @@ bool CDDeviceHandle::readTOC (TOC* lpToc, bool useMSF)
|
|||
s.SRB_CDBLen = 0x0A;
|
||||
s.SRB_PostProc = event;
|
||||
s.CDBByte[0] = 0x43;
|
||||
s.CDBByte[1] = (BYTE)(useMSF ? 0x02 : 0x00);
|
||||
s.CDBByte[1] = 0x00;
|
||||
s.CDBByte[7] = 0x03;
|
||||
s.CDBByte[8] = 0x24;
|
||||
|
||||
|
|
@ -245965,11 +246006,6 @@ static int getAddressOf (const TOCTRACK* const t)
|
|||
(((DWORD)t->addr[2]) << 8) + ((DWORD)t->addr[3]);
|
||||
}
|
||||
|
||||
static int getMSFAddressOf (const TOCTRACK* const t)
|
||||
{
|
||||
return 60 * t->addr[1] + t->addr[2];
|
||||
}
|
||||
|
||||
static const int samplesPerFrame = 44100 / 75;
|
||||
static const int bytesPerFrame = samplesPerFrame * 4;
|
||||
|
||||
|
|
@ -246083,7 +246119,6 @@ AudioCDReader::AudioCDReader (void* handle_)
|
|||
|
||||
sampleRate = 44100.0;
|
||||
bitsPerSample = 16;
|
||||
lengthInSamples = getPositionOfTrackStart (numTracks);
|
||||
numChannels = 2;
|
||||
usesFloatingPointData = false;
|
||||
|
||||
|
|
@ -246189,7 +246224,7 @@ bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int sta
|
|||
|
||||
// sometimes the read fails for just the very last couple of blocks, so
|
||||
// we'll ignore and errors in the last half-second of the disk..
|
||||
ok = startSampleInFile > (trackStarts [numTracks] - 20000);
|
||||
ok = startSampleInFile > (trackStartSamples [getNumTracks()] - 20000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -246204,50 +246239,35 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
return ((CDDeviceWrapper*) handle)->cdH->readTOC (&toc, false);
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return numTracks;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
return (trackNum >= 0 && trackNum <= numTracks) ? trackStarts [trackNum] * samplesPerFrame
|
||||
: 0;
|
||||
return ((CDDeviceWrapper*) handle)->cdH->readTOC (&toc);
|
||||
}
|
||||
|
||||
void AudioCDReader::refreshTrackLengths()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
zeromem (trackStarts, sizeof (trackStarts));
|
||||
trackStartSamples.clear();
|
||||
zeromem (audioTracks, sizeof (audioTracks));
|
||||
|
||||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
if (((CDDeviceWrapper*)handle)->cdH->readTOC (&toc, false))
|
||||
if (((CDDeviceWrapper*)handle)->cdH->readTOC (&toc))
|
||||
{
|
||||
numTracks = 1 + toc.lastTrack - toc.firstTrack;
|
||||
int numTracks = 1 + toc.lastTrack - toc.firstTrack;
|
||||
|
||||
for (int i = 0; i <= numTracks; ++i)
|
||||
{
|
||||
trackStarts[i] = getAddressOf (&toc.tracks[i]);
|
||||
audioTracks[i] = ((toc.tracks[i].ADR & 4) == 0);
|
||||
trackStartSamples.add (samplesPerFrame * getAddressOf (&toc.tracks [i]));
|
||||
audioTracks [i] = ((toc.tracks[i].ADR & 4) == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numTracks = 0;
|
||||
}
|
||||
|
||||
lengthInSamples = getPositionOfTrackStart (getNumTracks());
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return (trackNum >= 0 && trackNum <= numTracks) ? audioTracks [trackNum]
|
||||
: false;
|
||||
return trackNum >= 0 && trackNum < getNumTracks() && audioTracks [trackNum];
|
||||
}
|
||||
|
||||
void AudioCDReader::enableIndexScanning (bool b)
|
||||
|
|
@ -246393,44 +246413,6 @@ const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return indexes;
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
refreshTrackLengths();
|
||||
|
||||
if (numTracks > 0)
|
||||
{
|
||||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
if (((CDDeviceWrapper*) handle)->cdH->readTOC (&toc, true))
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (int i = numTracks; --i >= 0;)
|
||||
{
|
||||
int j = getMSFAddressOf (&toc.tracks[i]);
|
||||
|
||||
while (j > 0)
|
||||
{
|
||||
n += (j % 10);
|
||||
j /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 0)
|
||||
{
|
||||
const int t = getMSFAddressOf (&toc.tracks[numTracks])
|
||||
- getMSFAddressOf (&toc.tracks[0]);
|
||||
|
||||
return ((n % 0xff) << 24) | (t << 8) | numTracks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioCDReader::ejectDisk()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
|
|
@ -261365,16 +261347,6 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
return false;
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return false;
|
||||
|
|
@ -261394,11 +261366,6 @@ const Array<int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return Array<int>();
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*** End of inlined file: juce_linux_AudioCDReader.cpp ***/
|
||||
|
||||
|
|
@ -261838,34 +261805,30 @@ void SystemStats::initialiseStats()
|
|||
{
|
||||
initialised = true;
|
||||
|
||||
#if JUCE_MAC
|
||||
// extremely annoying: adding this line stops the apple menu items from working. Of
|
||||
// course, not adding it means that carbon windows (e.g. in plugins) won't get
|
||||
// any events.
|
||||
//NSApplicationLoad();
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
#if JUCE_MAC
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
|
||||
#if JUCE_INTEL
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
#if JUCE_INTEL
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
#else
|
||||
cpuFlags.hasMMX = false;
|
||||
cpuFlags.hasSSE = false;
|
||||
cpuFlags.hasSSE2 = false;
|
||||
cpuFlags.has3DNow = false;
|
||||
#endif
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
#else
|
||||
cpuFlags.hasMMX = false;
|
||||
cpuFlags.hasSSE = false;
|
||||
cpuFlags.hasSSE2 = false;
|
||||
cpuFlags.has3DNow = false;
|
||||
#endif
|
||||
|
||||
#if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#else
|
||||
cpuFlags.numCpus = (int) MPProcessors();
|
||||
#endif
|
||||
#if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#else
|
||||
cpuFlags.numCpus = (int) MPProcessors();
|
||||
#endif
|
||||
|
||||
mach_timebase_info_data_t timebase;
|
||||
(void) mach_timebase_info (&timebase);
|
||||
|
|
@ -265558,6 +265521,9 @@ END_JUCE_NAMESPACE
|
|||
[self addSubview: hiddenTextField];
|
||||
hiddenTextField.delegate = self;
|
||||
|
||||
hiddenTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
hiddenTextField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -274322,20 +274288,97 @@ void AudioCDReader::ejectDisk()
|
|||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_USE_CDREADER
|
||||
|
||||
static void juce_findCDs (Array<File>& cds)
|
||||
namespace CDReaderHelpers
|
||||
{
|
||||
File volumes ("/Volumes");
|
||||
volumes.findChildFiles (cds, File::findDirectories, false);
|
||||
inline const XmlElement* getElementForKey (const XmlElement& xml, const String& key)
|
||||
{
|
||||
forEachXmlChildElementWithTagName (xml, child, "key")
|
||||
if (child->getAllSubText() == key)
|
||||
return child->getNextElement();
|
||||
|
||||
for (int i = cds.size(); --i >= 0;)
|
||||
if (! cds.getReference(i).getChildFile (".TOC.plist").exists())
|
||||
cds.remove (i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getIntValueForKey (const XmlElement& xml, const String& key, int defaultValue = -1)
|
||||
{
|
||||
const XmlElement* const block = getElementForKey (xml, key);
|
||||
return block != 0 ? block->getAllSubText().getIntValue() : defaultValue;
|
||||
}
|
||||
|
||||
// Get the track offsets for a CD given an XmlElement representing its TOC.Plist.
|
||||
// Returns NULL on success, otherwise a const char* representing an error.
|
||||
static const char* getTrackOffsets (XmlDocument& xmlDocument, Array<int>& offsets)
|
||||
{
|
||||
const ScopedPointer<XmlElement> xml (xmlDocument.getDocumentElement());
|
||||
if (xml == 0)
|
||||
return "Couldn't parse XML in file";
|
||||
|
||||
const XmlElement* const dict = xml->getChildByName ("dict");
|
||||
if (dict == 0)
|
||||
return "Couldn't get top level dictionary";
|
||||
|
||||
const XmlElement* const sessions = getElementForKey (*dict, "Sessions");
|
||||
if (sessions == 0)
|
||||
return "Couldn't find sessions key";
|
||||
|
||||
const XmlElement* const session = sessions->getFirstChildElement();
|
||||
if (session == 0)
|
||||
return "Couldn't find first session";
|
||||
|
||||
const int leadOut = getIntValueForKey (*session, "Leadout Block");
|
||||
if (leadOut < 0)
|
||||
return "Couldn't find Leadout Block";
|
||||
|
||||
const XmlElement* const trackArray = getElementForKey (*session, "Track Array");
|
||||
if (trackArray == 0)
|
||||
return "Couldn't find Track Array";
|
||||
|
||||
forEachXmlChildElement (*trackArray, track)
|
||||
{
|
||||
const int trackValue = getIntValueForKey (*track, "Start Block");
|
||||
if (trackValue < 0)
|
||||
return "Couldn't find Start Block in the track";
|
||||
|
||||
offsets.add (trackValue * AudioCDReader::samplesPerFrame - 88200);
|
||||
}
|
||||
|
||||
offsets.add (leadOut * AudioCDReader::samplesPerFrame - 88200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void findDevices (Array<File>& cds)
|
||||
{
|
||||
File volumes ("/Volumes");
|
||||
volumes.findChildFiles (cds, File::findDirectories, false);
|
||||
|
||||
for (int i = cds.size(); --i >= 0;)
|
||||
if (! cds.getReference(i).getChildFile (".TOC.plist").exists())
|
||||
cds.remove (i);
|
||||
}
|
||||
|
||||
struct TrackSorter
|
||||
{
|
||||
static int getCDTrackNumber (const File& file)
|
||||
{
|
||||
return file.getFileName().initialSectionContainingOnly ("0123456789").getIntValue();
|
||||
}
|
||||
|
||||
static int compareElements (const File& first, const File& second)
|
||||
{
|
||||
const int firstTrack = getCDTrackNumber (first);
|
||||
const int secondTrack = getCDTrackNumber (second);
|
||||
|
||||
jassert (firstTrack > 0 && secondTrack > 0);
|
||||
|
||||
return firstTrack - secondTrack;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const StringArray AudioCDReader::getAvailableCDNames()
|
||||
{
|
||||
Array<File> cds;
|
||||
juce_findCDs (cds);
|
||||
CDReaderHelpers::findDevices (cds);
|
||||
|
||||
StringArray names;
|
||||
|
||||
|
|
@ -274348,7 +274391,7 @@ const StringArray AudioCDReader::getAvailableCDNames()
|
|||
AudioCDReader* AudioCDReader::createReaderForCD (const int index)
|
||||
{
|
||||
Array<File> cds;
|
||||
juce_findCDs (cds);
|
||||
CDReaderHelpers::findDevices (cds);
|
||||
|
||||
if (cds[index].exists())
|
||||
return new AudioCDReader (cds[index]);
|
||||
|
|
@ -274378,51 +274421,23 @@ void AudioCDReader::refreshTrackLengths()
|
|||
{
|
||||
tracks.clear();
|
||||
trackStartSamples.clear();
|
||||
lengthInSamples = 0;
|
||||
|
||||
volumeDir.findChildFiles (tracks, File::findFiles | File::ignoreHiddenFiles, false, "*.aiff");
|
||||
|
||||
struct CDTrackSorter
|
||||
{
|
||||
static int getCDTrackNumber (const File& file)
|
||||
{
|
||||
return file.getFileName()
|
||||
.initialSectionContainingOnly ("0123456789")
|
||||
.getIntValue();
|
||||
}
|
||||
|
||||
static int compareElements (const File& first, const File& second)
|
||||
{
|
||||
const int firstTrack = getCDTrackNumber (first);
|
||||
const int secondTrack = getCDTrackNumber (second);
|
||||
|
||||
jassert (firstTrack > 0 && secondTrack > 0);
|
||||
|
||||
return firstTrack - secondTrack;
|
||||
}
|
||||
};
|
||||
|
||||
CDTrackSorter sorter;
|
||||
CDReaderHelpers::TrackSorter sorter;
|
||||
tracks.sort (sorter);
|
||||
|
||||
AiffAudioFormat format;
|
||||
int sample = 0;
|
||||
const File toc (volumeDir.getChildFile (".TOC.plist"));
|
||||
|
||||
for (int i = 0; i < tracks.size(); ++i)
|
||||
if (toc.exists())
|
||||
{
|
||||
trackStartSamples.add (sample);
|
||||
XmlDocument doc (toc);
|
||||
const char* error = CDReaderHelpers::getTrackOffsets (doc, trackStartSamples);
|
||||
(void) error; // could be logged..
|
||||
|
||||
FileInputStream* const in = tracks.getReference(i).createInputStream();
|
||||
|
||||
if (in != 0)
|
||||
{
|
||||
ScopedPointer <AudioFormatReader> r (format.createReaderFor (in, true));
|
||||
|
||||
if (r != 0)
|
||||
sample += (int) r->lengthInSamples;
|
||||
}
|
||||
lengthInSamples = trackStartSamples.getLast() - trackStartSamples.getFirst();
|
||||
}
|
||||
|
||||
trackStartSamples.add (sample);
|
||||
lengthInSamples = sample;
|
||||
}
|
||||
|
||||
bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
||||
|
|
@ -274484,19 +274499,9 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
return volumeDir.exists();
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return tracks.size();
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return trackStartSamples [trackNum];
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return tracks [trackNum] != File::nonexistent;
|
||||
return tracks [trackNum].hasFileExtension (".aiff");
|
||||
}
|
||||
|
||||
void AudioCDReader::enableIndexScanning (bool b)
|
||||
|
|
@ -274514,11 +274519,6 @@ const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return Array <int>();
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
return 0; //xxx
|
||||
}
|
||||
|
||||
#endif
|
||||
/*** End of inlined file: juce_mac_AudioCDReader.mm ***/
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 44
|
||||
#define JUCE_BUILDNUMBER 45
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -338,7 +338,7 @@
|
|||
reduce code size.
|
||||
*/
|
||||
#ifndef JUCE_USE_CDREADER
|
||||
#define JUCE_USE_CDREADER 0
|
||||
#define JUCE_USE_CDREADER 1
|
||||
#endif
|
||||
|
||||
/** JUCE_USE_CAMERA: Enables web-cam support using the CameraDevice class (Mac and Windows).
|
||||
|
|
@ -30460,7 +30460,8 @@ public:
|
|||
|
||||
/** Finds the sample offset of the start of a track.
|
||||
|
||||
@param trackNum the track number, where 0 is the first track.
|
||||
@param trackNum the track number, where trackNum = 0 is the first track
|
||||
and trackNum = getNumTracks() means the end of the CD.
|
||||
*/
|
||||
int getPositionOfTrackStart (int trackNum) const;
|
||||
|
||||
|
|
@ -30470,6 +30471,11 @@ public:
|
|||
*/
|
||||
bool isTrackAudio (int trackNum) const;
|
||||
|
||||
/** Returns an array of sample offsets for the start of each track, followed by
|
||||
the sample position of the end of the CD.
|
||||
*/
|
||||
const Array<int>& getTrackOffsets() const;
|
||||
|
||||
/** Refreshes the object's table of contents.
|
||||
|
||||
If the disc has been ejected and a different one put in since this
|
||||
|
|
@ -30519,21 +30525,22 @@ public:
|
|||
*/
|
||||
void ejectDisk();
|
||||
|
||||
static const int framesPerSecond = 75;
|
||||
static const int samplesPerFrame = 44100 / framesPerSecond;
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
Array<int> trackStartSamples;
|
||||
|
||||
#if JUCE_MAC
|
||||
File volumeDir;
|
||||
Array<File> tracks;
|
||||
Array<int> trackStartSamples;
|
||||
int currentReaderTrack;
|
||||
ScopedPointer <AudioFormatReader> reader;
|
||||
AudioCDReader (const File& volume);
|
||||
|
||||
#elif JUCE_WINDOWS
|
||||
int numTracks;
|
||||
int trackStarts[100];
|
||||
bool audioTracks [100];
|
||||
void* handle;
|
||||
bool indexingEnabled;
|
||||
|
|
|
|||
69
src/audio/audio_file_formats/juce_AudioCDReader.cpp
Normal file
69
src/audio/audio_file_formats/juce_AudioCDReader.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../../core/juce_StandardHeader.h"
|
||||
|
||||
#if JUCE_USE_CDREADER
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#include "juce_AudioCDReader.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return trackStartSamples.size() - 1;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return trackStartSamples [trackNum];
|
||||
}
|
||||
|
||||
const Array<int>& AudioCDReader::getTrackOffsets() const
|
||||
{
|
||||
return trackStartSamples;
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
int checksum = 0;
|
||||
const int numTracks = getNumTracks();
|
||||
|
||||
for (int i = 0; i < numTracks; ++i)
|
||||
for (int offset = (trackStartSamples.getUnchecked(i) + 88200) / 44100; offset > 0; offset /= 10)
|
||||
checksum += offset % 10;
|
||||
|
||||
const int length = (trackStartSamples.getLast() - trackStartSamples.getFirst()) / 44100;
|
||||
|
||||
// CCLLLLTT: checksum, length, tracks
|
||||
return ((checksum & 0xff) << 24) | (length << 8) | numTracks;
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -87,7 +87,8 @@ public:
|
|||
|
||||
/** Finds the sample offset of the start of a track.
|
||||
|
||||
@param trackNum the track number, where 0 is the first track.
|
||||
@param trackNum the track number, where trackNum = 0 is the first track
|
||||
and trackNum = getNumTracks() means the end of the CD.
|
||||
*/
|
||||
int getPositionOfTrackStart (int trackNum) const;
|
||||
|
||||
|
|
@ -97,6 +98,11 @@ public:
|
|||
*/
|
||||
bool isTrackAudio (int trackNum) const;
|
||||
|
||||
/** Returns an array of sample offsets for the start of each track, followed by
|
||||
the sample position of the end of the CD.
|
||||
*/
|
||||
const Array<int>& getTrackOffsets() const;
|
||||
|
||||
/** Refreshes the object's table of contents.
|
||||
|
||||
If the disc has been ejected and a different one put in since this
|
||||
|
|
@ -146,22 +152,24 @@ public:
|
|||
*/
|
||||
void ejectDisk();
|
||||
|
||||
//==============================================================================
|
||||
static const int framesPerSecond = 75;
|
||||
static const int samplesPerFrame = 44100 / framesPerSecond;
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
Array<int> trackStartSamples;
|
||||
|
||||
#if JUCE_MAC
|
||||
File volumeDir;
|
||||
Array<File> tracks;
|
||||
Array<int> trackStartSamples;
|
||||
int currentReaderTrack;
|
||||
ScopedPointer <AudioFormatReader> reader;
|
||||
AudioCDReader (const File& volume);
|
||||
|
||||
#elif JUCE_WINDOWS
|
||||
int numTracks;
|
||||
int trackStarts[100];
|
||||
bool audioTracks [100];
|
||||
void* handle;
|
||||
bool indexingEnabled;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 44
|
||||
#define JUCE_BUILDNUMBER 45
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../io/streams/juce_BufferedInputStream.h"
|
||||
#include "../core/juce_PlatformUtilities.h"
|
||||
#include "../text/juce_LocalisedStrings.h"
|
||||
#include "../text/juce_XmlDocument.h"
|
||||
#include "../utilities/juce_DeletedAtShutdown.h"
|
||||
#include "../application/juce_Application.h"
|
||||
#include "../utilities/juce_SystemClipboard.h"
|
||||
|
|
@ -77,6 +78,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../gui/components/filebrowser/juce_FileChooser.h"
|
||||
#include "../audio/audio_file_formats/juce_AudioCDBurner.h"
|
||||
#include "../audio/audio_file_formats/juce_AudioCDReader.h"
|
||||
#include "../audio/audio_file_formats/juce_AiffAudioFormat.h"
|
||||
#include "../audio/audio_sources/juce_AudioSource.h"
|
||||
#include "../audio/dsp/juce_AudioDataConverters.h"
|
||||
#include "../audio/devices/juce_AudioIODeviceType.h"
|
||||
|
|
|
|||
|
|
@ -64,16 +64,6 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
return false;
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return false;
|
||||
|
|
@ -93,9 +83,4 @@ const Array<int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return Array<int>();
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -173,6 +173,9 @@ END_JUCE_NAMESPACE
|
|||
[self addSubview: hiddenTextField];
|
||||
hiddenTextField.delegate = self;
|
||||
|
||||
hiddenTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
hiddenTextField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,20 +28,98 @@
|
|||
#if JUCE_INCLUDED_FILE && JUCE_USE_CDREADER
|
||||
|
||||
//==============================================================================
|
||||
static void juce_findCDs (Array<File>& cds)
|
||||
namespace CDReaderHelpers
|
||||
{
|
||||
File volumes ("/Volumes");
|
||||
volumes.findChildFiles (cds, File::findDirectories, false);
|
||||
inline const XmlElement* getElementForKey (const XmlElement& xml, const String& key)
|
||||
{
|
||||
forEachXmlChildElementWithTagName (xml, child, "key")
|
||||
if (child->getAllSubText() == key)
|
||||
return child->getNextElement();
|
||||
|
||||
for (int i = cds.size(); --i >= 0;)
|
||||
if (! cds.getReference(i).getChildFile (".TOC.plist").exists())
|
||||
cds.remove (i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getIntValueForKey (const XmlElement& xml, const String& key, int defaultValue = -1)
|
||||
{
|
||||
const XmlElement* const block = getElementForKey (xml, key);
|
||||
return block != 0 ? block->getAllSubText().getIntValue() : defaultValue;
|
||||
}
|
||||
|
||||
// Get the track offsets for a CD given an XmlElement representing its TOC.Plist.
|
||||
// Returns NULL on success, otherwise a const char* representing an error.
|
||||
static const char* getTrackOffsets (XmlDocument& xmlDocument, Array<int>& offsets)
|
||||
{
|
||||
const ScopedPointer<XmlElement> xml (xmlDocument.getDocumentElement());
|
||||
if (xml == 0)
|
||||
return "Couldn't parse XML in file";
|
||||
|
||||
const XmlElement* const dict = xml->getChildByName ("dict");
|
||||
if (dict == 0)
|
||||
return "Couldn't get top level dictionary";
|
||||
|
||||
const XmlElement* const sessions = getElementForKey (*dict, "Sessions");
|
||||
if (sessions == 0)
|
||||
return "Couldn't find sessions key";
|
||||
|
||||
const XmlElement* const session = sessions->getFirstChildElement();
|
||||
if (session == 0)
|
||||
return "Couldn't find first session";
|
||||
|
||||
const int leadOut = getIntValueForKey (*session, "Leadout Block");
|
||||
if (leadOut < 0)
|
||||
return "Couldn't find Leadout Block";
|
||||
|
||||
const XmlElement* const trackArray = getElementForKey (*session, "Track Array");
|
||||
if (trackArray == 0)
|
||||
return "Couldn't find Track Array";
|
||||
|
||||
forEachXmlChildElement (*trackArray, track)
|
||||
{
|
||||
const int trackValue = getIntValueForKey (*track, "Start Block");
|
||||
if (trackValue < 0)
|
||||
return "Couldn't find Start Block in the track";
|
||||
|
||||
offsets.add (trackValue * AudioCDReader::samplesPerFrame - 88200);
|
||||
}
|
||||
|
||||
offsets.add (leadOut * AudioCDReader::samplesPerFrame - 88200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void findDevices (Array<File>& cds)
|
||||
{
|
||||
File volumes ("/Volumes");
|
||||
volumes.findChildFiles (cds, File::findDirectories, false);
|
||||
|
||||
for (int i = cds.size(); --i >= 0;)
|
||||
if (! cds.getReference(i).getChildFile (".TOC.plist").exists())
|
||||
cds.remove (i);
|
||||
}
|
||||
|
||||
struct TrackSorter
|
||||
{
|
||||
static int getCDTrackNumber (const File& file)
|
||||
{
|
||||
return file.getFileName().initialSectionContainingOnly ("0123456789").getIntValue();
|
||||
}
|
||||
|
||||
static int compareElements (const File& first, const File& second)
|
||||
{
|
||||
const int firstTrack = getCDTrackNumber (first);
|
||||
const int secondTrack = getCDTrackNumber (second);
|
||||
|
||||
jassert (firstTrack > 0 && secondTrack > 0);
|
||||
|
||||
return firstTrack - secondTrack;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const StringArray AudioCDReader::getAvailableCDNames()
|
||||
{
|
||||
Array<File> cds;
|
||||
juce_findCDs (cds);
|
||||
CDReaderHelpers::findDevices (cds);
|
||||
|
||||
StringArray names;
|
||||
|
||||
|
|
@ -54,7 +132,7 @@ const StringArray AudioCDReader::getAvailableCDNames()
|
|||
AudioCDReader* AudioCDReader::createReaderForCD (const int index)
|
||||
{
|
||||
Array<File> cds;
|
||||
juce_findCDs (cds);
|
||||
CDReaderHelpers::findDevices (cds);
|
||||
|
||||
if (cds[index].exists())
|
||||
return new AudioCDReader (cds[index]);
|
||||
|
|
@ -84,51 +162,23 @@ void AudioCDReader::refreshTrackLengths()
|
|||
{
|
||||
tracks.clear();
|
||||
trackStartSamples.clear();
|
||||
lengthInSamples = 0;
|
||||
|
||||
volumeDir.findChildFiles (tracks, File::findFiles | File::ignoreHiddenFiles, false, "*.aiff");
|
||||
|
||||
struct CDTrackSorter
|
||||
{
|
||||
static int getCDTrackNumber (const File& file)
|
||||
{
|
||||
return file.getFileName()
|
||||
.initialSectionContainingOnly ("0123456789")
|
||||
.getIntValue();
|
||||
}
|
||||
|
||||
static int compareElements (const File& first, const File& second)
|
||||
{
|
||||
const int firstTrack = getCDTrackNumber (first);
|
||||
const int secondTrack = getCDTrackNumber (second);
|
||||
|
||||
jassert (firstTrack > 0 && secondTrack > 0);
|
||||
|
||||
return firstTrack - secondTrack;
|
||||
}
|
||||
};
|
||||
|
||||
CDTrackSorter sorter;
|
||||
CDReaderHelpers::TrackSorter sorter;
|
||||
tracks.sort (sorter);
|
||||
|
||||
AiffAudioFormat format;
|
||||
int sample = 0;
|
||||
const File toc (volumeDir.getChildFile (".TOC.plist"));
|
||||
|
||||
for (int i = 0; i < tracks.size(); ++i)
|
||||
if (toc.exists())
|
||||
{
|
||||
trackStartSamples.add (sample);
|
||||
XmlDocument doc (toc);
|
||||
const char* error = CDReaderHelpers::getTrackOffsets (doc, trackStartSamples);
|
||||
(void) error; // could be logged..
|
||||
|
||||
FileInputStream* const in = tracks.getReference(i).createInputStream();
|
||||
|
||||
if (in != 0)
|
||||
{
|
||||
ScopedPointer <AudioFormatReader> r (format.createReaderFor (in, true));
|
||||
|
||||
if (r != 0)
|
||||
sample += (int) r->lengthInSamples;
|
||||
}
|
||||
lengthInSamples = trackStartSamples.getLast() - trackStartSamples.getFirst();
|
||||
}
|
||||
|
||||
trackStartSamples.add (sample);
|
||||
lengthInSamples = sample;
|
||||
}
|
||||
|
||||
bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
||||
|
|
@ -190,19 +240,9 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
return volumeDir.exists();
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return tracks.size();
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
return trackStartSamples [trackNum];
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return tracks [trackNum] != File::nonexistent;
|
||||
return tracks [trackNum].hasFileExtension (".aiff");
|
||||
}
|
||||
|
||||
void AudioCDReader::enableIndexScanning (bool b)
|
||||
|
|
@ -220,9 +260,4 @@ const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return Array <int>();
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
return 0; //xxx
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -78,34 +78,30 @@ void SystemStats::initialiseStats()
|
|||
{
|
||||
initialised = true;
|
||||
|
||||
#if JUCE_MAC
|
||||
// extremely annoying: adding this line stops the apple menu items from working. Of
|
||||
// course, not adding it means that carbon windows (e.g. in plugins) won't get
|
||||
// any events.
|
||||
//NSApplicationLoad();
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
#if JUCE_MAC
|
||||
[NSApplication sharedApplication];
|
||||
#endif
|
||||
|
||||
#if JUCE_INTEL
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
#if JUCE_INTEL
|
||||
unsigned int familyModel, extFeatures;
|
||||
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
|
||||
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
#else
|
||||
cpuFlags.hasMMX = false;
|
||||
cpuFlags.hasSSE = false;
|
||||
cpuFlags.hasSSE2 = false;
|
||||
cpuFlags.has3DNow = false;
|
||||
#endif
|
||||
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
|
||||
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
|
||||
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
|
||||
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
|
||||
#else
|
||||
cpuFlags.hasMMX = false;
|
||||
cpuFlags.hasSSE = false;
|
||||
cpuFlags.hasSSE2 = false;
|
||||
cpuFlags.has3DNow = false;
|
||||
#endif
|
||||
|
||||
#if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#else
|
||||
cpuFlags.numCpus = (int) MPProcessors();
|
||||
#endif
|
||||
#if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
cpuFlags.numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount];
|
||||
#else
|
||||
cpuFlags.numCpus = (int) MPProcessors();
|
||||
#endif
|
||||
|
||||
mach_timebase_info_data_t timebase;
|
||||
(void) mach_timebase_info (&timebase);
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ public:
|
|||
CloseHandle (scsiHandle);
|
||||
}
|
||||
|
||||
bool readTOC (TOC* lpToc, bool useMSF);
|
||||
bool readTOC (TOC* lpToc);
|
||||
bool readAudio (CDReadBuffer* buffer, CDReadBuffer* overlapBuffer = 0);
|
||||
void openDrawer (bool shouldBeOpen);
|
||||
|
||||
|
|
@ -1206,7 +1206,7 @@ int CDController::getLastIndex()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
bool CDDeviceHandle::readTOC (TOC* lpToc, bool useMSF)
|
||||
bool CDDeviceHandle::readTOC (TOC* lpToc)
|
||||
{
|
||||
HANDLE event = CreateEvent (0, TRUE, FALSE, 0);
|
||||
|
||||
|
|
@ -1224,7 +1224,7 @@ bool CDDeviceHandle::readTOC (TOC* lpToc, bool useMSF)
|
|||
s.SRB_CDBLen = 0x0A;
|
||||
s.SRB_PostProc = event;
|
||||
s.CDBByte[0] = 0x43;
|
||||
s.CDBByte[1] = (BYTE)(useMSF ? 0x02 : 0x00);
|
||||
s.CDBByte[1] = 0x00;
|
||||
s.CDBByte[7] = 0x03;
|
||||
s.CDBByte[8] = 0x24;
|
||||
|
||||
|
|
@ -1596,11 +1596,6 @@ static int getAddressOf (const TOCTRACK* const t)
|
|||
(((DWORD)t->addr[2]) << 8) + ((DWORD)t->addr[3]);
|
||||
}
|
||||
|
||||
static int getMSFAddressOf (const TOCTRACK* const t)
|
||||
{
|
||||
return 60 * t->addr[1] + t->addr[2];
|
||||
}
|
||||
|
||||
static const int samplesPerFrame = 44100 / 75;
|
||||
static const int bytesPerFrame = samplesPerFrame * 4;
|
||||
|
||||
|
|
@ -1715,7 +1710,6 @@ AudioCDReader::AudioCDReader (void* handle_)
|
|||
|
||||
sampleRate = 44100.0;
|
||||
bitsPerSample = 16;
|
||||
lengthInSamples = getPositionOfTrackStart (numTracks);
|
||||
numChannels = 2;
|
||||
usesFloatingPointData = false;
|
||||
|
||||
|
|
@ -1821,7 +1815,7 @@ bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int sta
|
|||
|
||||
// sometimes the read fails for just the very last couple of blocks, so
|
||||
// we'll ignore and errors in the last half-second of the disk..
|
||||
ok = startSampleInFile > (trackStarts [numTracks] - 20000);
|
||||
ok = startSampleInFile > (trackStartSamples [getNumTracks()] - 20000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1836,50 +1830,35 @@ bool AudioCDReader::isCDStillPresent() const
|
|||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
return ((CDDeviceWrapper*) handle)->cdH->readTOC (&toc, false);
|
||||
}
|
||||
|
||||
int AudioCDReader::getNumTracks() const
|
||||
{
|
||||
return numTracks;
|
||||
}
|
||||
|
||||
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
return (trackNum >= 0 && trackNum <= numTracks) ? trackStarts [trackNum] * samplesPerFrame
|
||||
: 0;
|
||||
return ((CDDeviceWrapper*) handle)->cdH->readTOC (&toc);
|
||||
}
|
||||
|
||||
void AudioCDReader::refreshTrackLengths()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
zeromem (trackStarts, sizeof (trackStarts));
|
||||
trackStartSamples.clear();
|
||||
zeromem (audioTracks, sizeof (audioTracks));
|
||||
|
||||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
if (((CDDeviceWrapper*)handle)->cdH->readTOC (&toc, false))
|
||||
if (((CDDeviceWrapper*)handle)->cdH->readTOC (&toc))
|
||||
{
|
||||
numTracks = 1 + toc.lastTrack - toc.firstTrack;
|
||||
int numTracks = 1 + toc.lastTrack - toc.firstTrack;
|
||||
|
||||
for (int i = 0; i <= numTracks; ++i)
|
||||
{
|
||||
trackStarts[i] = getAddressOf (&toc.tracks[i]);
|
||||
audioTracks[i] = ((toc.tracks[i].ADR & 4) == 0);
|
||||
trackStartSamples.add (samplesPerFrame * getAddressOf (&toc.tracks [i]));
|
||||
audioTracks [i] = ((toc.tracks[i].ADR & 4) == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numTracks = 0;
|
||||
}
|
||||
|
||||
lengthInSamples = getPositionOfTrackStart (getNumTracks());
|
||||
}
|
||||
|
||||
bool AudioCDReader::isTrackAudio (int trackNum) const
|
||||
{
|
||||
return (trackNum >= 0 && trackNum <= numTracks) ? audioTracks [trackNum]
|
||||
: false;
|
||||
return trackNum >= 0 && trackNum < getNumTracks() && audioTracks [trackNum];
|
||||
}
|
||||
|
||||
void AudioCDReader::enableIndexScanning (bool b)
|
||||
|
|
@ -2025,44 +2004,6 @@ const Array <int> AudioCDReader::findIndexesInTrack (const int trackNumber)
|
|||
return indexes;
|
||||
}
|
||||
|
||||
int AudioCDReader::getCDDBId()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
refreshTrackLengths();
|
||||
|
||||
if (numTracks > 0)
|
||||
{
|
||||
TOC toc;
|
||||
zerostruct (toc);
|
||||
|
||||
if (((CDDeviceWrapper*) handle)->cdH->readTOC (&toc, true))
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (int i = numTracks; --i >= 0;)
|
||||
{
|
||||
int j = getMSFAddressOf (&toc.tracks[i]);
|
||||
|
||||
while (j > 0)
|
||||
{
|
||||
n += (j % 10);
|
||||
j /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 0)
|
||||
{
|
||||
const int t = getMSFAddressOf (&toc.tracks[numTracks])
|
||||
- getMSFAddressOf (&toc.tracks[0]);
|
||||
|
||||
return ((n % 0xff) << 24) | (t << 8) | numTracks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioCDReader::ejectDisk()
|
||||
{
|
||||
using namespace CDReaderHelpers;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue