mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
parent
7eb7de4778
commit
af097645d3
24 changed files with 3953 additions and 3271 deletions
|
|
@ -131,6 +131,7 @@ OBJECTS := \
|
|||
$(OBJDIR)/juce_AudioThumbnailCache.o \
|
||||
$(OBJDIR)/juce_FlacAudioFormat.o \
|
||||
$(OBJDIR)/juce_OggVorbisAudioFormat.o \
|
||||
$(OBJDIR)/juce_QuickTimeAudioFormat.o \
|
||||
$(OBJDIR)/juce_WavAudioFormat.o \
|
||||
$(OBJDIR)/bitmath.o \
|
||||
$(OBJDIR)/bitreader.o \
|
||||
|
|
@ -926,6 +927,11 @@ $(OBJDIR)/juce_OggVorbisAudioFormat.o: ../../src/juce_appframework/audio/audio_f
|
|||
@echo $(notdir $<)
|
||||
@$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/juce_QuickTimeAudioFormat.o: ../../src/juce_appframework/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp
|
||||
-@$(CMD_MKOBJDIR)
|
||||
@echo $(notdir $<)
|
||||
@$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/juce_WavAudioFormat.o: ../../src/juce_appframework/audio/audio_file_formats/juce_WavAudioFormat.cpp
|
||||
-@$(CMD_MKOBJDIR)
|
||||
@echo $(notdir $<)
|
||||
|
|
|
|||
|
|
@ -198,6 +198,11 @@ bool File::isOnHardDisk() const throw()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool File::isHidden() const throw()
|
||||
{
|
||||
return getFileName().startsWithChar (T('.'));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */; };
|
||||
84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */; };
|
||||
84052DE408D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */; };
|
||||
84052DE508D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */; };
|
||||
|
|
@ -204,6 +203,7 @@
|
|||
846927DF0A49ABE600314975 /* juce_RectanglePlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 846927DD0A49ABE600314975 /* juce_RectanglePlacement.h */; };
|
||||
846927E10A49ABFD00314975 /* juce_SVGParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846927E00A49ABFD00314975 /* juce_SVGParser.cpp */; };
|
||||
847824810D7816A00082A5C5 /* juce_AudioCDBurner.h in Headers */ = {isa = PBXBuildFile; fileRef = 8478247F0D7816A00082A5C5 /* juce_AudioCDBurner.h */; };
|
||||
847D06470DD88D1100DF6A61 /* juce_mac_Network.mm in Sources */ = {isa = PBXBuildFile; fileRef = 847D06460DD88D1100DF6A61 /* juce_mac_Network.mm */; };
|
||||
847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F72D70C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp */; };
|
||||
847F72DC0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */; };
|
||||
847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */; };
|
||||
|
|
@ -225,7 +225,6 @@
|
|||
84A4882C08A22E2400752A2B /* juce_mac_Files.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */; };
|
||||
84A4882D08A22E2400752A2B /* juce_mac_Fonts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */; };
|
||||
84A4882E08A22E2400752A2B /* juce_mac_Messaging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */; };
|
||||
84A4882F08A22E2400752A2B /* juce_mac_Network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882408A22E2400752A2B /* juce_mac_Network.cpp */; };
|
||||
84A4883008A22E2400752A2B /* juce_mac_SystemStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882508A22E2400752A2B /* juce_mac_SystemStats.cpp */; };
|
||||
84A4883108A22E2400752A2B /* juce_mac_Threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882608A22E2400752A2B /* juce_mac_Threads.cpp */; };
|
||||
84A4883208A22E2400752A2B /* juce_mac_Windowing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882708A22E2400752A2B /* juce_mac_Windowing.cpp */; };
|
||||
|
|
@ -584,6 +583,7 @@
|
|||
84BC4E300C8DD38C00FA249B /* juce_GenericAudioProcessorEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BC4E280C8DD38C00FA249B /* juce_GenericAudioProcessorEditor.h */; };
|
||||
84C0EA5E0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84C0EA5C0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.cpp */; };
|
||||
84C0EA5F0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84C0EA5D0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.h */; };
|
||||
84CE8A410DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84CE8A400DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm */; };
|
||||
84D296BD09B763190026C535 /* juce_PropertiesFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D296BB09B763190026C535 /* juce_PropertiesFile.cpp */; };
|
||||
84D296BE09B763190026C535 /* juce_PropertiesFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D296BC09B763190026C535 /* juce_PropertiesFile.h */; };
|
||||
84E8209409729D2A0097675B /* juce_AudioFormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E8209209729D2A0097675B /* juce_AudioFormatManager.cpp */; };
|
||||
|
|
@ -693,7 +693,6 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_AudioCDBurner.cpp; sourceTree = "<group>"; };
|
||||
84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_mac_HTTPStream.h; sourceTree = "<group>"; };
|
||||
84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToneGeneratorAudioSource.cpp; sourceTree = "<group>"; };
|
||||
84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ToneGeneratorAudioSource.h; sourceTree = "<group>"; };
|
||||
|
|
@ -893,6 +892,7 @@
|
|||
846927DD0A49ABE600314975 /* juce_RectanglePlacement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_RectanglePlacement.h; sourceTree = "<group>"; };
|
||||
846927E00A49ABFD00314975 /* juce_SVGParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_SVGParser.cpp; sourceTree = "<group>"; };
|
||||
8478247F0D7816A00082A5C5 /* juce_AudioCDBurner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioCDBurner.h; sourceTree = "<group>"; };
|
||||
847D06460DD88D1100DF6A61 /* juce_mac_Network.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_Network.mm; sourceTree = "<group>"; };
|
||||
847F72D70C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DirectoryContentsDisplayComponent.cpp; path = filebrowser/juce_DirectoryContentsDisplayComponent.cpp; sourceTree = "<group>"; };
|
||||
847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_DirectoryContentsDisplayComponent.h; path = filebrowser/juce_DirectoryContentsDisplayComponent.h; sourceTree = "<group>"; };
|
||||
847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_FileTreeComponent.cpp; path = filebrowser/juce_FileTreeComponent.cpp; sourceTree = "<group>"; };
|
||||
|
|
@ -914,7 +914,6 @@
|
|||
84A4882108A22E2400752A2B /* juce_mac_Files.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Files.cpp; path = platform_specific_code/juce_mac_Files.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Fonts.cpp; path = platform_specific_code/juce_mac_Fonts.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Messaging.cpp; path = platform_specific_code/juce_mac_Messaging.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882408A22E2400752A2B /* juce_mac_Network.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Network.cpp; path = platform_specific_code/juce_mac_Network.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882508A22E2400752A2B /* juce_mac_SystemStats.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_SystemStats.cpp; path = platform_specific_code/juce_mac_SystemStats.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882608A22E2400752A2B /* juce_mac_Threads.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Threads.cpp; path = platform_specific_code/juce_mac_Threads.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84A4882708A22E2400752A2B /* juce_mac_Windowing.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Windowing.cpp; path = platform_specific_code/juce_mac_Windowing.cpp; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -1273,6 +1272,7 @@
|
|||
84BC4E280C8DD38C00FA249B /* juce_GenericAudioProcessorEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_GenericAudioProcessorEditor.h; sourceTree = "<group>"; };
|
||||
84C0EA5C0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_IIRFilterAudioSource.cpp; path = ../../src/juce_appframework/audio/audio_sources/juce_IIRFilterAudioSource.cpp; sourceTree = SOURCE_ROOT; };
|
||||
84C0EA5D0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_IIRFilterAudioSource.h; path = ../../src/juce_appframework/audio/audio_sources/juce_IIRFilterAudioSource.h; sourceTree = SOURCE_ROOT; };
|
||||
84CE8A400DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_AudioCDBurner.mm; sourceTree = "<group>"; };
|
||||
84D296BB09B763190026C535 /* juce_PropertiesFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_PropertiesFile.cpp; sourceTree = "<group>"; };
|
||||
84D296BC09B763190026C535 /* juce_PropertiesFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_PropertiesFile.h; sourceTree = "<group>"; };
|
||||
84E8209209729D2A0097675B /* juce_AudioFormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioFormatManager.cpp; sourceTree = "<group>"; };
|
||||
|
|
@ -1379,7 +1379,7 @@
|
|||
84FED3C80CAA96DA00003997 /* juce_FileDragAndDropTarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_FileDragAndDropTarget.h; sourceTree = "<group>"; };
|
||||
84FFAF290C6C8F2B009F6E72 /* juce_FileSearchPathListComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_FileSearchPathListComponent.cpp; path = filebrowser/juce_FileSearchPathListComponent.cpp; sourceTree = "<group>"; };
|
||||
84FFAF2A0C6C8F2B009F6E72 /* juce_FileSearchPathListComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_FileSearchPathListComponent.h; path = filebrowser/juce_FileSearchPathListComponent.h; sourceTree = "<group>"; };
|
||||
D2AAC046055464E500DB518D /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D2AAC046055464E500DB518D /* libjuce.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjuce.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -1419,7 +1419,7 @@
|
|||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2AAC046055464E500DB518D /* libjucedebug.a */,
|
||||
D2AAC046055464E500DB518D /* libjuce.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1542,7 +1542,7 @@
|
|||
84A4881C08A22E2400752A2B /* mac specific code */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */,
|
||||
84CE8A400DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm */,
|
||||
84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */,
|
||||
84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */,
|
||||
84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */,
|
||||
|
|
@ -1551,7 +1551,7 @@
|
|||
84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */,
|
||||
84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */,
|
||||
84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */,
|
||||
84A4882408A22E2400752A2B /* juce_mac_Network.cpp */,
|
||||
847D06460DD88D1100DF6A61 /* juce_mac_Network.mm */,
|
||||
84A4882508A22E2400752A2B /* juce_mac_SystemStats.cpp */,
|
||||
84A4882608A22E2400752A2B /* juce_mac_Threads.cpp */,
|
||||
84A4882708A22E2400752A2B /* juce_mac_Windowing.cpp */,
|
||||
|
|
@ -2924,7 +2924,7 @@
|
|||
);
|
||||
name = Juce;
|
||||
productName = Juce;
|
||||
productReference = D2AAC046055464E500DB518D /* libjucedebug.a */;
|
||||
productReference = D2AAC046055464E500DB518D /* libjuce.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
|
@ -2955,7 +2955,6 @@
|
|||
84A4882C08A22E2400752A2B /* juce_mac_Files.cpp in Sources */,
|
||||
84A4882D08A22E2400752A2B /* juce_mac_Fonts.cpp in Sources */,
|
||||
84A4882E08A22E2400752A2B /* juce_mac_Messaging.cpp in Sources */,
|
||||
84A4882F08A22E2400752A2B /* juce_mac_Network.cpp in Sources */,
|
||||
84A4883008A22E2400752A2B /* juce_mac_SystemStats.cpp in Sources */,
|
||||
84A4883108A22E2400752A2B /* juce_mac_Threads.cpp in Sources */,
|
||||
84A4883208A22E2400752A2B /* juce_mac_Windowing.cpp in Sources */,
|
||||
|
|
@ -3319,7 +3318,8 @@
|
|||
8495BB8E0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp in Sources */,
|
||||
8495BB940D806BDA001D9C0B /* juce_FileInputSource.cpp in Sources */,
|
||||
84581EEA0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.cpp in Sources */,
|
||||
84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */,
|
||||
84CE8A410DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm in Sources */,
|
||||
847D06470DD88D1100DF6A61 /* juce_mac_Network.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARCHS = i386
|
||||
ARCHS = i386 ppc
|
||||
|
||||
// For 10.2 (and later) compatibility, use these values:
|
||||
//GCC_VERSION_ppc = 3.3
|
||||
|
|
@ -8,10 +8,10 @@ ARCHS = i386
|
|||
//SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.2.8.sdk
|
||||
|
||||
// For 10.3 (and later) compatibility, use these instead:
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.5
|
||||
// MACOSX_DEPLOYMENT_TARGET_ppc = 10.3
|
||||
SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk
|
||||
// SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.3
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4
|
||||
SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk
|
||||
SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk
|
||||
|
||||
// For 10.4 (and later) compatibility, use these instead:
|
||||
// MACOSX_DEPLOYMENT_TARGET = 10.4
|
||||
|
|
|
|||
|
|
@ -29,48 +29,82 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
|
||||
/*#include "../../../src/juce_core/basics/juce_StandardHeader.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int juce_findDiskBurnerDevices (const char** devices);
|
||||
void* juce_openDiskBurnerDevice (int deviceIndex);
|
||||
void juce_deleteDiskBurnerDevice (void* diskBurnerDevice);
|
||||
bool juce_isDiskPresentInDevice (void* diskBurnerDevice);
|
||||
int juce_getNumAvailableAudioBlocks (void* diskBurnerDevice);
|
||||
typedef bool (*diskBurnCallback) (void* userRef, float progress);
|
||||
void juce_performBurn (void* diskBurnerDevice, diskBurnCallback callback);
|
||||
}
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
AudioCDBurner::AudioCDBurner (const int deviceIndex)
|
||||
: internal (0)
|
||||
{
|
||||
internal = juce_openDiskBurnerDevice (deviceIndex);
|
||||
}
|
||||
|
||||
AudioCDBurner::~AudioCDBurner()
|
||||
{
|
||||
if (internal != 0)
|
||||
juce_deleteDiskBurnerDevice (internal);
|
||||
}
|
||||
|
||||
AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex)
|
||||
{
|
||||
return 0;
|
||||
AudioCDBurner* b = new AudioCDBurner (deviceIndex);
|
||||
|
||||
if (b->internal == 0)
|
||||
deleteAndZero (b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
const StringArray AudioCDBurner::findAvailableDevices()
|
||||
{
|
||||
int num = juce_findDiskBurnerDevices (0);
|
||||
char** names = (char**) juce_calloc (sizeof (char*) * num);
|
||||
for (int i = num; --i >= 0;)
|
||||
names[i] = (char*) juce_calloc (2048);
|
||||
|
||||
juce_findDiskBurnerDevices ((const char**) names);
|
||||
|
||||
StringArray s;
|
||||
|
||||
for (int i = num; --i >= 0;)
|
||||
{
|
||||
s.add (String::fromUTF8 ((juce::uint8*) names[i]));
|
||||
juce_free (names[i]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool AudioCDBurner::isDiskPresent() const
|
||||
{
|
||||
return false;
|
||||
return juce_isDiskPresentInDevice (internal);
|
||||
}
|
||||
|
||||
int AudioCDBurner::getNumAvailableAudioBlocks() const
|
||||
{
|
||||
return 0;
|
||||
return juce_getNumAvailableAudioBlocks (internal);
|
||||
}
|
||||
|
||||
bool AudioCDBurner::addAudioTrack (AudioFormatReader& source, int numSamples)
|
||||
{
|
||||
juce_BeginAudioTrack (internal);
|
||||
juce_AddSamplesToAudioTrack (internal, samples, num);
|
||||
juce_EndAudioTrack (internal);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -85,4 +119,4 @@ const String AudioCDBurner::burn (BurnProgressListener* listener,
|
|||
return String::empty;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
END_JUCE_NAMESPACE*/
|
||||
453
build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm
Normal file
453
build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
|
||||
|
||||
#if JUCE_USE_CDBURNER
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <DiscRecording/DiscRecording.h>
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h"
|
||||
#include "../../../src/juce_appframework/audio/audio_sources/juce_AudioSource.h"
|
||||
#include "../../../src/juce_appframework/audio/dsp/juce_AudioDataConverters.h"
|
||||
#include "../../../src/juce_core/threads/juce_Thread.h"
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
@interface OpenDiskDevice : NSObject
|
||||
{
|
||||
DRDevice* device;
|
||||
|
||||
NSMutableArray* tracks;
|
||||
}
|
||||
|
||||
- (OpenDiskDevice*) initWithDevice: (DRDevice*) device;
|
||||
- (void) dealloc;
|
||||
- (bool) isDiskPresent;
|
||||
- (int) getNumAvailableAudioBlocks;
|
||||
- (void) addSourceTrack: (juce::AudioSource*) source numSamples: (int) numSamples_;
|
||||
- (void) burn: (juce::AudioCDBurner::BurnProgressListener*) listener errorString: (juce::String*) error
|
||||
ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting;
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
@interface AudioTrackProducer : NSObject
|
||||
{
|
||||
juce::AudioSource* source;
|
||||
int readPosition, lengthInFrames;
|
||||
}
|
||||
|
||||
- (AudioTrackProducer*) init: (int) lengthInFrames;
|
||||
- (AudioTrackProducer*) initWithAudioSource: (juce::AudioSource*) source numSamples: (int) lengthInSamples;
|
||||
- (void) dealloc;
|
||||
- (void) setupTrackProperties: (DRTrack*) track;
|
||||
|
||||
- (void) cleanupTrackAfterBurn: (DRTrack*) track;
|
||||
- (BOOL) cleanupTrackAfterVerification:(DRTrack*)track;
|
||||
- (uint64_t) estimateLengthOfTrack:(DRTrack*)track;
|
||||
- (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
|
||||
toMedia:(NSDictionary*)mediaInfo;
|
||||
- (BOOL) prepareTrackForVerification:(DRTrack*)track;
|
||||
- (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags;
|
||||
- (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags;
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags;
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
@implementation OpenDiskDevice
|
||||
|
||||
- (OpenDiskDevice*) initWithDevice: (DRDevice*) device_
|
||||
{
|
||||
[super init];
|
||||
|
||||
device = device_;
|
||||
tracks = [[NSMutableArray alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[tracks release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (bool) isDiskPresent
|
||||
{
|
||||
NSLog ([[device status] description]);
|
||||
return [device isValid];
|
||||
}
|
||||
|
||||
- (int) getNumAvailableAudioBlocks
|
||||
{
|
||||
NSLog ([[device status] description]);
|
||||
return [[[[device status] objectForKey: DRDeviceMediaInfoKey]
|
||||
objectForKey: DRDeviceMediaBlocksFreeKey] intValue];
|
||||
}
|
||||
|
||||
- (void) addSourceTrack: (juce::AudioSource*) source_ numSamples: (int) numSamples_
|
||||
{
|
||||
AudioTrackProducer* p = [[AudioTrackProducer alloc] initWithAudioSource: source_ numSamples: numSamples_];
|
||||
DRTrack* t = [[DRTrack alloc] initWithProducer: p];
|
||||
[p setupTrackProperties: t];
|
||||
|
||||
[tracks addObject: t];
|
||||
|
||||
[t release];
|
||||
[p release];
|
||||
}
|
||||
|
||||
- (void) burn: (juce::AudioCDBurner::BurnProgressListener*) listener errorString: (juce::String*) error
|
||||
ejectAfterwards: (bool) shouldEject isFake: (bool) peformFakeBurnForTesting
|
||||
{
|
||||
DRBurn* burn = [DRBurn burnForDevice: device];
|
||||
|
||||
if (! [device acquireExclusiveAccess])
|
||||
{
|
||||
*error = "Couldn't open or write to the CD device";
|
||||
return;
|
||||
}
|
||||
|
||||
[device acquireMediaReservation];
|
||||
|
||||
NSMutableDictionary* d = [[burn properties] mutableCopy];
|
||||
[d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey];
|
||||
[d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey];
|
||||
[burn setProperties: d];
|
||||
[d release];
|
||||
|
||||
[burn writeLayout: tracks];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
juce::Thread::sleep (300);
|
||||
float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue];
|
||||
|
||||
if (listener != 0 && listener->audioCDBurnProgress (progress))
|
||||
{
|
||||
[burn abort];
|
||||
*error = "User cancelled the write operation";
|
||||
break;
|
||||
}
|
||||
|
||||
if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateFailed])
|
||||
{
|
||||
*error = "Write operation failed";
|
||||
break;
|
||||
}
|
||||
else if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateDone])
|
||||
{
|
||||
if (shouldEject)
|
||||
[device openTray];
|
||||
|
||||
break;
|
||||
}
|
||||
NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey]
|
||||
objectForKey: DRErrorStatusErrorStringKey];
|
||||
|
||||
if ([err length] > 0)
|
||||
{
|
||||
*error = juce::String::fromUTF8 ((juce::uint8*) [err UTF8String]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[device releaseMediaReservation];
|
||||
[device releaseExclusiveAccess];
|
||||
}
|
||||
@end
|
||||
|
||||
//==============================================================================
|
||||
@implementation AudioTrackProducer
|
||||
|
||||
- (AudioTrackProducer*) init: (int) lengthInFrames_
|
||||
{
|
||||
lengthInFrames = lengthInFrames_;
|
||||
readPosition = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setupTrackProperties: (DRTrack*) track
|
||||
{
|
||||
NSMutableDictionary* p = [[track properties] mutableCopy];
|
||||
[p setObject: [DRMSF msfWithFrames: lengthInFrames] forKey: DRTrackLengthKey];
|
||||
[p setObject: [NSNumber numberWithUnsignedShort: 2048] forKey: DRBlockSizeKey];
|
||||
[p setObject: [NSNumber numberWithInt: 16] forKey: DRDataFormKey];
|
||||
[p setObject: [NSNumber numberWithInt: 8] forKey: DRBlockTypeKey];
|
||||
[p setObject: [NSNumber numberWithInt: 4] forKey: DRTrackModeKey];
|
||||
[p setObject: [NSNumber numberWithInt: 0] forKey: DRSessionFormatKey];
|
||||
[track setProperties: p];
|
||||
[p release];
|
||||
}
|
||||
|
||||
- (AudioTrackProducer*) initWithAudioSource: (juce::AudioSource*) source_ numSamples: (int) lengthInSamples
|
||||
{
|
||||
AudioTrackProducer* s = [self init: lengthInSamples / (44100 / 75)];
|
||||
|
||||
if (s != nil)
|
||||
s->source = source_;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (source != 0)
|
||||
{
|
||||
source->releaseResources();
|
||||
delete source;
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) cleanupTrackAfterBurn: (DRTrack*) track
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL) cleanupTrackAfterVerification:(DRTrack*)track
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
- (uint64_t) estimateLengthOfTrack:(DRTrack*)track
|
||||
{
|
||||
return lengthInFrames;
|
||||
}
|
||||
|
||||
- (BOOL) prepareTrack:(DRTrack*)track forBurn:(DRBurn*)burn
|
||||
toMedia:(NSDictionary*)mediaInfo
|
||||
{
|
||||
if (source != 0)
|
||||
source->prepareToPlay (44100 / 75, 44100);
|
||||
|
||||
readPosition = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
- (BOOL) prepareTrackForVerification:(DRTrack*)track
|
||||
{
|
||||
if (source != 0)
|
||||
source->prepareToPlay (44100 / 75, 44100);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (uint32_t) produceDataForTrack:(DRTrack*)track intoBuffer:(char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags
|
||||
{
|
||||
if (source != 0)
|
||||
{
|
||||
const int numSamples = juce::jmin (bufferLength / 4, (lengthInFrames * (44100 / 75)) - readPosition);
|
||||
|
||||
if (numSamples > 0)
|
||||
{
|
||||
juce::AudioSampleBuffer tempBuffer (2, numSamples);
|
||||
|
||||
juce::AudioSourceChannelInfo info;
|
||||
info.buffer = &tempBuffer;
|
||||
info.startSample = 0;
|
||||
info.numSamples = numSamples;
|
||||
|
||||
source->getNextAudioBlock (info);
|
||||
|
||||
juce::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (0),
|
||||
buffer, numSamples, 4);
|
||||
juce::AudioDataConverters::convertFloatToInt16LE (tempBuffer.getSampleData (1),
|
||||
buffer + 2, numSamples, 4);
|
||||
|
||||
readPosition += numSamples;
|
||||
}
|
||||
|
||||
return numSamples * 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (uint32_t) producePreGapForTrack:(DRTrack*)track
|
||||
intoBuffer:(char*)buffer length:(uint32_t)bufferLength
|
||||
atAddress:(uint64_t)address blockSize:(uint32_t)blockSize
|
||||
ioFlags:(uint32_t*)flags
|
||||
{
|
||||
zeromem (buffer, bufferLength);
|
||||
return bufferLength;
|
||||
}
|
||||
|
||||
- (BOOL) verifyDataForTrack:(DRTrack*)track inBuffer:(const char*)buffer
|
||||
length:(uint32_t)bufferLength atAddress:(uint64_t)address
|
||||
blockSize:(uint32_t)blockSize ioFlags:(uint32_t*)flags
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
AudioCDBurner::AudioCDBurner (const int deviceIndex)
|
||||
: internal (0)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
OpenDiskDevice* dev = [[OpenDiskDevice alloc] initWithDevice: [[DRDevice devices] objectAtIndex: deviceIndex]];
|
||||
|
||||
internal = (void*) dev;
|
||||
[pool release];
|
||||
}
|
||||
|
||||
AudioCDBurner::~AudioCDBurner()
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
OpenDiskDevice* dev = (OpenDiskDevice*) internal;
|
||||
|
||||
if (dev != 0)
|
||||
[dev release];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
AudioCDBurner* b = new AudioCDBurner (deviceIndex);
|
||||
|
||||
if (b->internal == 0)
|
||||
deleteAndZero (b);
|
||||
|
||||
[pool release];
|
||||
return b;
|
||||
}
|
||||
|
||||
static NSArray* findDiskBurnerDevices()
|
||||
{
|
||||
NSMutableArray* results = [NSMutableArray array];
|
||||
NSArray* devs = [DRDevice devices];
|
||||
|
||||
if (devs != 0)
|
||||
{
|
||||
int num = [devs count];
|
||||
int i;
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
NSDictionary* dic = [[devs objectAtIndex: i] info];
|
||||
NSString* name = [dic valueForKey: DRDeviceProductNameKey];
|
||||
if (name != nil)
|
||||
[results addObject: name];
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
const StringArray AudioCDBurner::findAvailableDevices()
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
NSArray* names = findDiskBurnerDevices();
|
||||
StringArray s;
|
||||
|
||||
for (int i = 0; i < [names count]; ++i)
|
||||
s.add (String::fromUTF8 ((juce::uint8*) [[names objectAtIndex: i] UTF8String]));
|
||||
|
||||
[pool release];
|
||||
return s;
|
||||
}
|
||||
|
||||
bool AudioCDBurner::isDiskPresent() const
|
||||
{
|
||||
OpenDiskDevice* dev = (OpenDiskDevice*) internal;
|
||||
|
||||
return dev != 0 && [dev isDiskPresent];
|
||||
}
|
||||
|
||||
int AudioCDBurner::getNumAvailableAudioBlocks() const
|
||||
{
|
||||
OpenDiskDevice* dev = (OpenDiskDevice*) internal;
|
||||
|
||||
return [dev getNumAvailableAudioBlocks];
|
||||
}
|
||||
|
||||
bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamps)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
OpenDiskDevice* dev = (OpenDiskDevice*) internal;
|
||||
|
||||
if (dev != 0)
|
||||
{
|
||||
[dev addSourceTrack: source numSamples: numSamps];
|
||||
[pool release];
|
||||
return true;
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return false;
|
||||
}
|
||||
|
||||
const String AudioCDBurner::burn (juce::AudioCDBurner::BurnProgressListener* listener,
|
||||
const bool peformFakeBurnForTesting,
|
||||
const bool ejectDiscAfterwards)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
juce::String error ("Couldn't open or write to the CD device");
|
||||
|
||||
OpenDiskDevice* dev = (OpenDiskDevice*) internal;
|
||||
|
||||
if (dev != 0)
|
||||
{
|
||||
error = juce::String::empty;
|
||||
[dev burn: listener
|
||||
errorString: &error
|
||||
ejectAfterwards: ejectDiscAfterwards
|
||||
isFake: peformFakeBurnForTesting];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return error;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,393 +1,406 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
#define __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
|
||||
// (This file gets included by the mac + linux networking code)
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A HTTP input stream that uses sockets.
|
||||
*/
|
||||
class JUCE_HTTPSocketStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
JUCE_HTTPSocketStream()
|
||||
: statusCode (0),
|
||||
readPosition (0),
|
||||
socketHandle (-1),
|
||||
levelsOfRedirection (0),
|
||||
timeoutSeconds (15)
|
||||
{
|
||||
}
|
||||
|
||||
~JUCE_HTTPSocketStream()
|
||||
{
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool open (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost)
|
||||
{
|
||||
closeSocket();
|
||||
|
||||
String hostName, hostPath;
|
||||
int hostPort;
|
||||
|
||||
if (! decomposeURL (url, hostName, hostPath, hostPort))
|
||||
return false;
|
||||
|
||||
struct hostent* const host
|
||||
= gethostbyname ((const char*) hostName.toUTF8());
|
||||
|
||||
if (host == 0)
|
||||
return false;
|
||||
|
||||
struct sockaddr_in address;
|
||||
zerostruct (address);
|
||||
memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
|
||||
address.sin_family = host->h_addrtype;
|
||||
address.sin_port = htons (hostPort);
|
||||
|
||||
socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
|
||||
|
||||
if (socketHandle == -1)
|
||||
return false;
|
||||
|
||||
int receiveBufferSize = 16384;
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
||||
|
||||
if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
String proxyURL (getenv ("http_proxy"));
|
||||
|
||||
if (! proxyURL.startsWithIgnoreCase (T("http://")))
|
||||
proxyURL = String::empty;
|
||||
|
||||
const MemoryBlock requestHeader (createRequestHeader (hostName, hostPath,
|
||||
proxyURL, url,
|
||||
hostPort,
|
||||
headers, postData,
|
||||
isPost));
|
||||
|
||||
if (send (socketHandle, requestHeader.getData(), requestHeader.getSize(), 0)
|
||||
!= requestHeader.getSize())
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
const String responseHeader (readResponse());
|
||||
|
||||
if (responseHeader.isNotEmpty())
|
||||
{
|
||||
//DBG (responseHeader);
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (responseHeader);
|
||||
|
||||
statusCode = responseHeader.fromFirstOccurrenceOf (T(" "), false, false)
|
||||
.substring (0, 3).getIntValue();
|
||||
|
||||
|
||||
//int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
|
||||
//bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
|
||||
|
||||
String location (findHeaderItem (lines, T("Location:")));
|
||||
|
||||
if (statusCode >= 300 && statusCode < 400
|
||||
&& location.isNotEmpty())
|
||||
{
|
||||
if (! location.startsWithIgnoreCase (T("http://")))
|
||||
location = T("http://") + location;
|
||||
|
||||
if (levelsOfRedirection++ < 3)
|
||||
return open (location, headers, postData, isPost);
|
||||
}
|
||||
else
|
||||
{
|
||||
levelsOfRedirection = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int read (void* buffer, int bytesToRead)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return 0; // (timeout)
|
||||
|
||||
const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
|
||||
readPosition += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int statusCode, readPosition;
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
int socketHandle, levelsOfRedirection;
|
||||
const int timeoutSeconds;
|
||||
|
||||
//==============================================================================
|
||||
void closeSocket()
|
||||
{
|
||||
if (socketHandle >= 0)
|
||||
close (socketHandle);
|
||||
|
||||
socketHandle = -1;
|
||||
}
|
||||
|
||||
const MemoryBlock createRequestHeader (const String& hostName,
|
||||
const String& hostPath,
|
||||
const String& proxyURL,
|
||||
const String& originalURL,
|
||||
const int hostPort,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost)
|
||||
{
|
||||
String header (isPost ? "POST " : "GET ");
|
||||
|
||||
if (proxyURL.isEmpty())
|
||||
{
|
||||
header << hostPath << " HTTP/1.1\r\nHost: "
|
||||
<< hostName << ':' << hostPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
String proxyName, proxyPath;
|
||||
int proxyPort;
|
||||
|
||||
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
|
||||
return MemoryBlock();
|
||||
|
||||
header << originalURL << " HTTP/1.1\r\nHost: "
|
||||
<< proxyName << ':' << proxyPort;
|
||||
|
||||
/* xxx needs finishing
|
||||
const char* proxyAuth = getenv ("http_proxy_auth");
|
||||
if (proxyAuth != 0)
|
||||
header << T("\r\nProxy-Authorization: ") << Base64Encode (proxyAuth);
|
||||
*/
|
||||
}
|
||||
|
||||
header << "\r\nUser-Agent: JUCE/"
|
||||
<< JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
|
||||
<< "\r\nConnection: Close\r\n"
|
||||
<< headers << "\r\n";
|
||||
|
||||
MemoryBlock mb;
|
||||
mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
|
||||
mb.append (postData.getData(), postData.getSize());
|
||||
|
||||
return mb;
|
||||
}
|
||||
|
||||
const String readResponse()
|
||||
{
|
||||
int bytesRead = 0, numConsecutiveLFs = 0;
|
||||
MemoryBlock buffer (1024, true);
|
||||
|
||||
while (numConsecutiveLFs < 2 && bytesRead < 32768)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return String::empty; // (timeout)
|
||||
|
||||
buffer.ensureSize (bytesRead + 8, true);
|
||||
char* const dest = (char*) buffer.getData() + bytesRead;
|
||||
|
||||
if (recv (socketHandle, dest, 1, 0) == -1)
|
||||
return String::empty;
|
||||
|
||||
const char lastByte = *dest;
|
||||
++bytesRead;
|
||||
|
||||
if (lastByte == '\n')
|
||||
++numConsecutiveLFs;
|
||||
else if (lastByte != '\r')
|
||||
numConsecutiveLFs = 0;
|
||||
}
|
||||
|
||||
const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
|
||||
|
||||
if (header.startsWithIgnoreCase (T("HTTP/")))
|
||||
return header.trimEnd();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool decomposeURL (const String& url,
|
||||
String& host, String& path, int& port)
|
||||
{
|
||||
if (! url.startsWithIgnoreCase (T("http://")))
|
||||
return false;
|
||||
|
||||
const int nextSlash = url.indexOfChar (7, '/');
|
||||
int nextColon = url.indexOfChar (7, ':');
|
||||
if (nextColon > nextSlash && nextSlash > 0)
|
||||
nextColon = -1;
|
||||
|
||||
if (nextColon >= 0)
|
||||
{
|
||||
host = url.substring (7, nextColon);
|
||||
|
||||
if (nextSlash >= 0)
|
||||
port = url.substring (nextColon + 1, nextSlash).getIntValue();
|
||||
else
|
||||
port = url.substring (nextColon + 1).getIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
port = 80;
|
||||
|
||||
if (nextSlash >= 0)
|
||||
host = url.substring (7, nextSlash);
|
||||
else
|
||||
host = url.substring (7);
|
||||
}
|
||||
|
||||
if (nextSlash >= 0)
|
||||
path = url.substring (nextSlash);
|
||||
else
|
||||
path = T("/");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static const String findHeaderItem (const StringArray& lines, const String& itemName)
|
||||
{
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
if (lines[i].startsWithIgnoreCase (itemName))
|
||||
return lines[i].substring (itemName.length()).trim();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
bool juce_isOnLine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* juce_openInternetFile (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
|
||||
|
||||
if (s->open (url, headers, postData, isPost))
|
||||
return s;
|
||||
|
||||
delete s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
delete s;
|
||||
}
|
||||
|
||||
int juce_getStatusCodeFor (void* handle)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->statusCode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->read (buffer, bytesToRead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_seekInInternetFile (void* handle, int newPosition)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->readPosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
#define __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
|
||||
// (This file gets included by the mac + linux networking code)
|
||||
|
||||
//==============================================================================
|
||||
/** A HTTP input stream that uses sockets.
|
||||
*/
|
||||
class JUCE_HTTPSocketStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
JUCE_HTTPSocketStream()
|
||||
: statusCode (0),
|
||||
readPosition (0),
|
||||
socketHandle (-1),
|
||||
levelsOfRedirection (0),
|
||||
timeoutSeconds (15)
|
||||
{
|
||||
}
|
||||
|
||||
~JUCE_HTTPSocketStream()
|
||||
{
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool open (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext)
|
||||
{
|
||||
closeSocket();
|
||||
|
||||
String hostName, hostPath;
|
||||
int hostPort;
|
||||
|
||||
if (! decomposeURL (url, hostName, hostPath, hostPort))
|
||||
return false;
|
||||
|
||||
struct hostent* const host
|
||||
= gethostbyname ((const char*) hostName.toUTF8());
|
||||
|
||||
if (host == 0)
|
||||
return false;
|
||||
|
||||
struct sockaddr_in address;
|
||||
zerostruct (address);
|
||||
memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
|
||||
address.sin_family = host->h_addrtype;
|
||||
address.sin_port = htons (hostPort);
|
||||
|
||||
socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
|
||||
|
||||
if (socketHandle == -1)
|
||||
return false;
|
||||
|
||||
int receiveBufferSize = 16384;
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
||||
|
||||
#if JUCE_MAC
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
|
||||
#endif
|
||||
|
||||
if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
String proxyURL (getenv ("http_proxy"));
|
||||
|
||||
if (! proxyURL.startsWithIgnoreCase (T("http://")))
|
||||
proxyURL = String::empty;
|
||||
|
||||
const MemoryBlock requestHeader (createRequestHeader (hostName, hostPath,
|
||||
proxyURL, url,
|
||||
hostPort,
|
||||
headers, postData,
|
||||
isPost));
|
||||
|
||||
int totalHeaderSent = 0;
|
||||
|
||||
while (totalHeaderSent < requestHeader.getSize())
|
||||
{
|
||||
const int numToSend = jmin (1024, requestHeader.getSize() - totalHeaderSent);
|
||||
|
||||
if (send (socketHandle,
|
||||
((const char*) requestHeader.getData()) + totalHeaderSent,
|
||||
numToSend, 0)
|
||||
!= numToSend)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
totalHeaderSent += numToSend;
|
||||
|
||||
if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const String responseHeader (readResponse());
|
||||
|
||||
if (responseHeader.isNotEmpty())
|
||||
{
|
||||
//DBG (responseHeader);
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (responseHeader);
|
||||
|
||||
statusCode = responseHeader.fromFirstOccurrenceOf (T(" "), false, false)
|
||||
.substring (0, 3).getIntValue();
|
||||
|
||||
|
||||
//int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
|
||||
//bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
|
||||
|
||||
String location (findHeaderItem (lines, T("Location:")));
|
||||
|
||||
if (statusCode >= 300 && statusCode < 400
|
||||
&& location.isNotEmpty())
|
||||
{
|
||||
if (! location.startsWithIgnoreCase (T("http://")))
|
||||
location = T("http://") + location;
|
||||
|
||||
if (levelsOfRedirection++ < 3)
|
||||
return open (location, headers, postData, isPost, callback, callbackContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
levelsOfRedirection = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int read (void* buffer, int bytesToRead)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return 0; // (timeout)
|
||||
|
||||
const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
|
||||
readPosition += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int statusCode, readPosition;
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
int socketHandle, levelsOfRedirection;
|
||||
const int timeoutSeconds;
|
||||
|
||||
//==============================================================================
|
||||
void closeSocket()
|
||||
{
|
||||
if (socketHandle >= 0)
|
||||
close (socketHandle);
|
||||
|
||||
socketHandle = -1;
|
||||
}
|
||||
|
||||
const MemoryBlock createRequestHeader (const String& hostName,
|
||||
const String& hostPath,
|
||||
const String& proxyURL,
|
||||
const String& originalURL,
|
||||
const int hostPort,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost)
|
||||
{
|
||||
String header (isPost ? "POST " : "GET ");
|
||||
|
||||
if (proxyURL.isEmpty())
|
||||
{
|
||||
header << hostPath << " HTTP/1.0\r\nHost: "
|
||||
<< hostName << ':' << hostPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
String proxyName, proxyPath;
|
||||
int proxyPort;
|
||||
|
||||
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
|
||||
return MemoryBlock();
|
||||
|
||||
header << originalURL << " HTTP/1.0\r\nHost: "
|
||||
<< proxyName << ':' << proxyPort;
|
||||
|
||||
/* xxx needs finishing
|
||||
const char* proxyAuth = getenv ("http_proxy_auth");
|
||||
if (proxyAuth != 0)
|
||||
header << T("\r\nProxy-Authorization: ") << Base64Encode (proxyAuth);
|
||||
*/
|
||||
}
|
||||
|
||||
header << "\r\nUser-Agent: JUCE/"
|
||||
<< JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
|
||||
<< "\r\nConnection: Close\r\nContent-Length: "
|
||||
<< postData.getSize() << "\r\n"
|
||||
<< headers << "\r\n";
|
||||
|
||||
MemoryBlock mb;
|
||||
mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
|
||||
mb.append (postData.getData(), postData.getSize());
|
||||
|
||||
return mb;
|
||||
}
|
||||
|
||||
const String readResponse()
|
||||
{
|
||||
int bytesRead = 0, numConsecutiveLFs = 0;
|
||||
MemoryBlock buffer (1024, true);
|
||||
|
||||
while (numConsecutiveLFs < 2 && bytesRead < 32768)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return String::empty; // (timeout)
|
||||
|
||||
buffer.ensureSize (bytesRead + 8, true);
|
||||
char* const dest = (char*) buffer.getData() + bytesRead;
|
||||
|
||||
if (recv (socketHandle, dest, 1, 0) == -1)
|
||||
return String::empty;
|
||||
|
||||
const char lastByte = *dest;
|
||||
++bytesRead;
|
||||
|
||||
if (lastByte == '\n')
|
||||
++numConsecutiveLFs;
|
||||
else if (lastByte != '\r')
|
||||
numConsecutiveLFs = 0;
|
||||
}
|
||||
|
||||
const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
|
||||
|
||||
if (header.startsWithIgnoreCase (T("HTTP/")))
|
||||
return header.trimEnd();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool decomposeURL (const String& url,
|
||||
String& host, String& path, int& port)
|
||||
{
|
||||
if (! url.startsWithIgnoreCase (T("http://")))
|
||||
return false;
|
||||
|
||||
const int nextSlash = url.indexOfChar (7, '/');
|
||||
int nextColon = url.indexOfChar (7, ':');
|
||||
if (nextColon > nextSlash && nextSlash > 0)
|
||||
nextColon = -1;
|
||||
|
||||
if (nextColon >= 0)
|
||||
{
|
||||
host = url.substring (7, nextColon);
|
||||
|
||||
if (nextSlash >= 0)
|
||||
port = url.substring (nextColon + 1, nextSlash).getIntValue();
|
||||
else
|
||||
port = url.substring (nextColon + 1).getIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
port = 80;
|
||||
|
||||
if (nextSlash >= 0)
|
||||
host = url.substring (7, nextSlash);
|
||||
else
|
||||
host = url.substring (7);
|
||||
}
|
||||
|
||||
if (nextSlash >= 0)
|
||||
path = url.substring (nextSlash);
|
||||
else
|
||||
path = T("/");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static const String findHeaderItem (const StringArray& lines, const String& itemName)
|
||||
{
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
if (lines[i].startsWithIgnoreCase (itemName))
|
||||
return lines[i].substring (itemName.length()).trim();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool juce_isOnLine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* juce_openInternetFile (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
|
||||
|
||||
if (s->open (url, headers, postData, isPost,
|
||||
callback, callbackContext))
|
||||
return s;
|
||||
|
||||
delete s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
delete s;
|
||||
}
|
||||
|
||||
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->read (buffer, bytesToRead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_seekInInternetFile (void* handle, int newPosition)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->readPosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
|
||||
|
|
|
|||
202
build/macosx/platform_specific_code/juce_mac_Network.mm
Normal file
202
build/macosx/platform_specific_code/juce_mac_Network.mm
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <IOKit/IOKitLib.h>
|
||||
#import <IOKit/network/IOEthernetInterface.h>
|
||||
#import <IOKit/network/IONetworkInterface.h>
|
||||
#import <IOKit/network/IOEthernetController.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#include "../../../src/juce_core/text/juce_String.h"
|
||||
#include "../../../src/juce_core/basics/juce_Time.h"
|
||||
#include "../../../src/juce_core/basics/juce_SystemStats.h"
|
||||
#include "../../../src/juce_core/threads/juce_ScopedLock.h"
|
||||
#include "../../../src/juce_core/threads/juce_WaitableEvent.h"
|
||||
#include "../../../src/juce_core/threads/juce_Thread.h"
|
||||
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
|
||||
#include "../../../src/juce_core/text/juce_StringArray.h"
|
||||
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../src/juce_core/io/network/juce_URL.h"
|
||||
|
||||
#include "juce_mac_HTTPStream.h"
|
||||
|
||||
//==============================================================================
|
||||
static bool GetEthernetIterator (io_iterator_t* matchingServices) throw()
|
||||
{
|
||||
mach_port_t masterPort;
|
||||
|
||||
if (IOMasterPort (MACH_PORT_NULL, &masterPort) == KERN_SUCCESS)
|
||||
{
|
||||
CFMutableDictionaryRef dict = IOServiceMatching (kIOEthernetInterfaceClass);
|
||||
|
||||
if (dict != 0)
|
||||
{
|
||||
CFMutableDictionaryRef propDict = CFDictionaryCreateMutable (kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
if (propDict != 0)
|
||||
{
|
||||
CFDictionarySetValue (propDict, CFSTR (kIOPrimaryInterface), kCFBooleanTrue);
|
||||
|
||||
CFDictionarySetValue (dict, CFSTR (kIOPropertyMatchKey), propDict);
|
||||
CFRelease (propDict);
|
||||
}
|
||||
}
|
||||
|
||||
return IOServiceGetMatchingServices (masterPort, dict, matchingServices) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
|
||||
{
|
||||
int numResults = 0;
|
||||
io_iterator_t it;
|
||||
|
||||
if (GetEthernetIterator (&it))
|
||||
{
|
||||
io_object_t i;
|
||||
|
||||
while ((i = IOIteratorNext (it)) != 0)
|
||||
{
|
||||
io_object_t controller;
|
||||
|
||||
if (IORegistryEntryGetParentEntry (i, kIOServicePlane, &controller) == KERN_SUCCESS)
|
||||
{
|
||||
CFTypeRef data = IORegistryEntryCreateCFProperty (controller,
|
||||
CFSTR (kIOMACAddress),
|
||||
kCFAllocatorDefault,
|
||||
0);
|
||||
if (data != 0)
|
||||
{
|
||||
UInt8 addr [kIOEthernetAddressSize];
|
||||
zeromem (addr, sizeof (addr));
|
||||
|
||||
CFDataGetBytes ((CFDataRef) data, CFRangeMake (0, sizeof (addr)), addr);
|
||||
CFRelease (data);
|
||||
|
||||
int64 a = 0;
|
||||
for (int i = 6; --i >= 0;)
|
||||
a = (a << 8) | addr[i];
|
||||
|
||||
if (! littleEndian)
|
||||
a = (int64) swapByteOrder ((uint64) a);
|
||||
|
||||
if (numResults < maxNum)
|
||||
{
|
||||
*addresses++ = a;
|
||||
++numResults;
|
||||
}
|
||||
}
|
||||
|
||||
IOObjectRelease (controller);
|
||||
}
|
||||
|
||||
IOObjectRelease (i);
|
||||
}
|
||||
|
||||
IOObjectRelease (it);
|
||||
}
|
||||
|
||||
return numResults;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class AutoPool
|
||||
{
|
||||
public:
|
||||
AutoPool() { pool = [[NSAutoreleasePool alloc] init]; }
|
||||
~AutoPool() { [pool release]; }
|
||||
|
||||
private:
|
||||
NSAutoreleasePool* pool;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
|
||||
const String& emailSubject,
|
||||
const String& bodyText,
|
||||
const StringArray& filesToAttach)
|
||||
{
|
||||
const AutoPool pool;
|
||||
|
||||
String script;
|
||||
script << "tell application \"Mail\"\r\n"
|
||||
"set newMessage to make new outgoing message with properties {subject:\""
|
||||
<< emailSubject.replace (T("\""), T("\\\""))
|
||||
<< "\", content:\""
|
||||
<< bodyText.replace (T("\""), T("\\\""))
|
||||
<< "\" & return & return}\r\n"
|
||||
"tell newMessage\r\n"
|
||||
"set visible to true\r\n"
|
||||
"set sender to \"sdfsdfsdfewf\"\r\n"
|
||||
"make new to recipient at end of to recipients with properties {address:\""
|
||||
<< targetEmailAddress
|
||||
<< "\"}\r\n";
|
||||
|
||||
for (int i = 0; i < filesToAttach.size(); ++i)
|
||||
{
|
||||
script << "tell content\r\n"
|
||||
"make new attachment with properties {file name:\""
|
||||
<< filesToAttach[i].replace (T("\""), T("\\\""))
|
||||
<< "\"} at after the last paragraph\r\n"
|
||||
"end tell\r\n";
|
||||
}
|
||||
|
||||
script << "end tell\r\n"
|
||||
"end tell\r\n";
|
||||
|
||||
NSAppleScript* s = [[NSAppleScript alloc]
|
||||
initWithSource: [NSString stringWithUTF8String: (const char*) script.toUTF8()]];
|
||||
NSDictionary* error = 0;
|
||||
[s executeAndReturnError: &error];
|
||||
[s release];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
@ -191,8 +191,8 @@ public:
|
|||
CMProfileRef prof;
|
||||
CMGetSystemProfile (&prof);
|
||||
colourspace = CGColorSpaceCreateWithPlatformColorSpace (prof);
|
||||
|
||||
provider = CGDataProviderCreateWithData (0, imageData, h * lineStride, 0);
|
||||
CMCloseProfile (prof);
|
||||
}
|
||||
|
||||
MacBitmapImage::~MacBitmapImage()
|
||||
|
|
@ -806,10 +806,18 @@ public:
|
|||
Rect w;
|
||||
GetWindowBounds (windowRef, windowRegionToUse, &w);
|
||||
|
||||
RgnHandle rgn = NewRgn();
|
||||
SetRectRgn (rgn, 0, 0, w.right - w.left, w.bottom - w.top);
|
||||
UpdateControls (windowRef, rgn);
|
||||
DisposeRgn (rgn);
|
||||
const int offsetInWindowX = component->getScreenX() - getScreenX();
|
||||
const int offsetInWindowY = component->getScreenY() - getScreenY();
|
||||
|
||||
for (RectangleList::Iterator i (repainter->getRegionsNeedingRepaint()); i.next();)
|
||||
{
|
||||
const Rectangle& r = *i.getRectangle();
|
||||
w.left = offsetInWindowX + r.getX();
|
||||
w.top = offsetInWindowY + r.getY();
|
||||
w.right = offsetInWindowX + r.getRight();
|
||||
w.bottom = offsetInWindowY + r.getBottom();
|
||||
InvalWindowRect (windowRef, &w);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2348,7 +2348,8 @@ int AudioCDBurner::getNumAvailableAudioBlocks() const
|
|||
}
|
||||
|
||||
const String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener,
|
||||
const bool ejectDiscAfterwards)
|
||||
const bool ejectDiscAfterwards,
|
||||
const bool performFakeBurnForTesting)
|
||||
{
|
||||
CDBurnerInfo* const info = (CDBurnerInfo*) internal;
|
||||
|
||||
|
|
@ -2359,7 +2360,7 @@ const String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener,
|
|||
UINT_PTR cookie;
|
||||
HRESULT hr = info->discMaster->ProgressAdvise (info, &cookie);
|
||||
|
||||
hr = info->discMaster->RecordDisc (FALSE, // set this to TRUE to make it do a fake burn, without actually writing to the disc
|
||||
hr = info->discMaster->RecordDisc (performFakeBurnForTesting,
|
||||
ejectDiscAfterwards);
|
||||
|
||||
String error;
|
||||
|
|
@ -2381,69 +2382,11 @@ const String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener,
|
|||
return error;
|
||||
}
|
||||
|
||||
bool AudioCDBurner::addAudioTrack (AudioFormatReader& source, int numSamples)
|
||||
bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples)
|
||||
{
|
||||
CDBurnerInfo* const info = (CDBurnerInfo*) internal;
|
||||
if (source == 0)
|
||||
return false;
|
||||
|
||||
long bytesPerBlock;
|
||||
HRESULT hr = info->redbook->GetAudioBlockSize (&bytesPerBlock);
|
||||
|
||||
const int samplesPerBlock = bytesPerBlock / 4;
|
||||
bool ok = true;
|
||||
|
||||
hr = info->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4));
|
||||
|
||||
byte* const buffer = (byte*) juce_malloc (bytesPerBlock);
|
||||
|
||||
int* sourceBuffers[2];
|
||||
sourceBuffers[0] = (int*) juce_malloc (samplesPerBlock * 4);
|
||||
sourceBuffers[1] = (int*) juce_malloc (samplesPerBlock * 4);
|
||||
|
||||
int samplesDone = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
zeromem (buffer, bytesPerBlock);
|
||||
|
||||
if (! source.read (sourceBuffers, samplesDone, samplesPerBlock))
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
short* destBuffer = (short*) buffer;
|
||||
|
||||
for (int j = 0; j < samplesPerBlock; ++j)
|
||||
{
|
||||
*destBuffer++ = (short) (sourceBuffers [0][j] >> 16);
|
||||
*destBuffer++ = (short) (sourceBuffers [jmin (1, source.numChannels - 1)][j] >> 16);
|
||||
}
|
||||
|
||||
hr = info->redbook->AddAudioTrackBlocks (buffer, bytesPerBlock);
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
samplesDone += samplesPerBlock;
|
||||
|
||||
if (samplesDone >= numSamples)
|
||||
break;
|
||||
}
|
||||
|
||||
juce_free (sourceBuffers[0]);
|
||||
juce_free (sourceBuffers[1]);
|
||||
juce_free (buffer);
|
||||
|
||||
hr = info->redbook->CloseAudioTrack();
|
||||
|
||||
return ok && hr == S_OK;
|
||||
}
|
||||
|
||||
bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples)
|
||||
{
|
||||
CDBurnerInfo* const info = (CDBurnerInfo*) internal;
|
||||
|
||||
long bytesPerBlock;
|
||||
|
|
@ -2459,7 +2402,7 @@ bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples)
|
|||
AudioSampleBuffer sourceBuffer (2, samplesPerBlock);
|
||||
int samplesDone = 0;
|
||||
|
||||
source.prepareToPlay (samplesPerBlock, 44100.0);
|
||||
source->prepareToPlay (samplesPerBlock, 44100.0);
|
||||
|
||||
while (ok)
|
||||
{
|
||||
|
|
@ -2470,7 +2413,7 @@ bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples)
|
|||
info.startSample = 0;
|
||||
sourceBuffer.clear();
|
||||
|
||||
source.getNextAudioBlock (info);
|
||||
source->getNextAudioBlock (info);
|
||||
}
|
||||
|
||||
zeromem (buffer, bytesPerBlock);
|
||||
|
|
@ -2496,6 +2439,8 @@ bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples)
|
|||
|
||||
hr = info->redbook->CloseAudioTrack();
|
||||
|
||||
delete source;
|
||||
|
||||
return ok && hr == S_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,11 @@ bool juce_setFileReadOnly (const String& fileName,
|
|||
return SetFileAttributes (fileName, attr) != FALSE;
|
||||
}
|
||||
|
||||
bool File::isHidden() const throw()
|
||||
{
|
||||
return (GetFileAttributes (getFullPathName()) & FILE_ATTRIBUTE_HIDDEN) != 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool juce_deleteFile (const String& fileName) throw()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -225,26 +225,6 @@ int juce_seekInInternetFile (void* handle, int newPosition)
|
|||
}
|
||||
}
|
||||
|
||||
int juce_getStatusCodeFor (void* handle)
|
||||
{
|
||||
DWORD result = 404;
|
||||
const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
|
||||
|
||||
if (crs != 0)
|
||||
{
|
||||
DWORD index = 0;
|
||||
DWORD size = sizeof (result);
|
||||
|
||||
HttpQueryInfo (crs->request,
|
||||
HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
|
||||
&result,
|
||||
&size,
|
||||
&index);
|
||||
}
|
||||
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
if (handle != 0)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,7 @@
|
|||
namespace BinaryData
|
||||
{
|
||||
extern const char* audiodemo_cpp;
|
||||
const int audiodemo_cppSize = 23434;
|
||||
const int audiodemo_cppSize = 22793;
|
||||
|
||||
extern const char* cello_wav;
|
||||
const int cello_wavSize = 46348;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,89 +1,113 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
#define __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
|
||||
#include "juce_AudioFormatReader.h"
|
||||
#include "../audio_sources/juce_AudioSource.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class AudioCDBurner
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
static const StringArray findAvailableDevices();
|
||||
static AudioCDBurner* openDevice (const int deviceIndex);
|
||||
|
||||
~AudioCDBurner();
|
||||
|
||||
//==============================================================================
|
||||
bool isDiskPresent() const;
|
||||
|
||||
int getNumAvailableAudioBlocks() const;
|
||||
|
||||
bool addAudioTrack (AudioFormatReader& source, int numSamples);
|
||||
bool addAudioTrack (AudioSource& source, int numSamples);
|
||||
|
||||
/**
|
||||
|
||||
Return true to cancel the current burn operation
|
||||
*/
|
||||
class BurnProgressListener
|
||||
{
|
||||
public:
|
||||
BurnProgressListener() throw() {}
|
||||
virtual ~BurnProgressListener() {}
|
||||
|
||||
/** Called at intervals to report on the progress of the AudioCDBurner.
|
||||
|
||||
To cancel the burn, return true from this.
|
||||
*/
|
||||
virtual bool audioCDBurnProgress (float proportionComplete) = 0;
|
||||
};
|
||||
|
||||
const String burn (BurnProgressListener* listener,
|
||||
const bool ejectDiscAfterwards);
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
AudioCDBurner (const int deviceIndex);
|
||||
|
||||
void* internal;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
#define __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
|
||||
#include "juce_AudioFormatReader.h"
|
||||
#include "../audio_sources/juce_AudioSource.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class AudioCDBurner
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Returns a list of available optical drives.
|
||||
|
||||
Use openDevice() to open one of the items from this list.
|
||||
*/
|
||||
static const StringArray findAvailableDevices();
|
||||
|
||||
/** Tries to open one of the optical drives.
|
||||
|
||||
The deviceIndex is an index into the array returned by findAvailableDevices().
|
||||
*/
|
||||
static AudioCDBurner* openDevice (const int deviceIndex);
|
||||
|
||||
/** Destructor. */
|
||||
~AudioCDBurner();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if there's a writable disk in the drive.
|
||||
*/
|
||||
bool isDiskPresent() const;
|
||||
|
||||
/** Returns the number of free blocks on the disk.
|
||||
|
||||
There are 75 blocks per second, at 44100Hz.
|
||||
*/
|
||||
int getNumAvailableAudioBlocks() const;
|
||||
|
||||
/** Adds a track to be written.
|
||||
|
||||
The source passed-in here will be kept by this object, and it will
|
||||
be used and deleted at some point in the future, either during the
|
||||
burn() method or when this AudioCDBurner object is deleted. Your caller
|
||||
method shouldn't keep a reference to it or use it again after passing
|
||||
it in here.
|
||||
*/
|
||||
bool addAudioTrack (AudioSource* source, int numSamples);
|
||||
|
||||
/**
|
||||
|
||||
Return true to cancel the current burn operation
|
||||
*/
|
||||
class BurnProgressListener
|
||||
{
|
||||
public:
|
||||
BurnProgressListener() throw() {}
|
||||
virtual ~BurnProgressListener() {}
|
||||
|
||||
/** Called at intervals to report on the progress of the AudioCDBurner.
|
||||
|
||||
To cancel the burn, return true from this.
|
||||
*/
|
||||
virtual bool audioCDBurnProgress (float proportionComplete) = 0;
|
||||
};
|
||||
|
||||
const String burn (BurnProgressListener* listener,
|
||||
const bool ejectDiscAfterwards,
|
||||
const bool peformFakeBurnForTesting);
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
AudioCDBurner (const int deviceIndex);
|
||||
|
||||
void* internal;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ static void swapEndiannessIfNeeded (AudioThumbnailDataFormat* const d)
|
|||
AudioThumbnail::AudioThumbnail (const int orginalSamplesPerThumbnailSample_,
|
||||
AudioFormatManager& formatManagerToUse_,
|
||||
AudioThumbnailCache& cacheToUse)
|
||||
: cache (cacheToUse),
|
||||
formatManagerToUse (formatManagerToUse_),
|
||||
: formatManagerToUse (formatManagerToUse_),
|
||||
cache (cacheToUse),
|
||||
source (0),
|
||||
reader (0),
|
||||
orginalSamplesPerThumbnailSample (orginalSamplesPerThumbnailSample_)
|
||||
|
|
|
|||
|
|
@ -181,13 +181,13 @@ void ComboBox::changeItemText (const int itemId,
|
|||
item->name = newText;
|
||||
}
|
||||
|
||||
void ComboBox::clear()
|
||||
void ComboBox::clear (const bool dontSendChangeMessage)
|
||||
{
|
||||
items.clear();
|
||||
separatorPending = false;
|
||||
|
||||
if (! label->isEditable())
|
||||
setSelectedItemIndex (-1);
|
||||
setSelectedItemIndex (-1, dontSendChangeMessage);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -164,9 +164,12 @@ public:
|
|||
|
||||
/** Removes all the items from the drop-down list.
|
||||
|
||||
If this call causes the content to be cleared, then a change-message
|
||||
will be broadcast unless dontSendChangeMessage is true.
|
||||
|
||||
@see addItem, removeItem, getNumItems
|
||||
*/
|
||||
void clear();
|
||||
void clear (const bool dontSendChangeMessage = false);
|
||||
|
||||
/** Returns the number of items that have been added to the list.
|
||||
|
||||
|
|
|
|||
|
|
@ -627,8 +627,8 @@ bool TreeView::keyPressed (const KeyPress& key)
|
|||
void TreeView::itemsChanged() throw()
|
||||
{
|
||||
needsRecalculating = true;
|
||||
triggerAsyncUpdate();
|
||||
repaint();
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void TreeView::handleAsyncUpdate()
|
||||
|
|
|
|||
|
|
@ -346,6 +346,12 @@ public:
|
|||
bool setReadOnly (const bool shouldBeReadOnly,
|
||||
const bool applyRecursively = false) const throw();
|
||||
|
||||
/** Returns true if this file is a hidden or system file.
|
||||
|
||||
The criteria for deciding whether a file is hidden are platform-dependent.
|
||||
*/
|
||||
bool isHidden() const throw();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the last modification time of this file.
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,6 @@ void* juce_openInternetFile (const String& url,
|
|||
void juce_closeInternetFile (void* handle);
|
||||
int juce_readFromInternetFile (void* handle, void* dest, int bytesToRead);
|
||||
int juce_seekInInternetFile (void* handle, int newPosition);
|
||||
int juce_getStatusCodeFor (void* handle);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -204,11 +203,6 @@ public:
|
|||
return handle == 0;
|
||||
}
|
||||
|
||||
int getErrorCode() const
|
||||
{
|
||||
return juce_getStatusCodeFor (handle);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int64 getTotalLength()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue