1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-02 03:20:06 +00:00

Complete revamp of the Juce Demo's audio page, to include several tabs of handy demos, including audio recording, synths, playback, audio thumbnails and an automatic round-trip latency detector

This commit is contained in:
Julian Storer 2009-09-19 14:01:55 +01:00
parent 3954631795
commit 9aa0c05ac2
35 changed files with 2908 additions and 10617 deletions

View file

@ -1338,14 +1338,14 @@
84F1E70210403614006A1807 /* juce_AudioThumbnail.h */,
84F1E70310403614006A1807 /* juce_AudioThumbnailCache.cpp */,
84F1E70410403614006A1807 /* juce_AudioThumbnailCache.h */,
84F1E70510403614006A1807 /* juce_FlacAudioFormat.h */,
84F1E70610403614006A1807 /* juce_OggVorbisAudioFormat.h */,
84F1E70710403614006A1807 /* juce_QuickTimeAudioFormat.h */,
84F1E70810403614006A1807 /* juce_WavAudioFormat.h */,
84F1E70910403614006A1807 /* juce_WavAudioFormat.cpp */,
84F1E70A10403614006A1807 /* juce_QuickTimeAudioFormat.cpp */,
84F1E70B10403614006A1807 /* juce_FlacAudioFormat.cpp */,
84F1E70510403614006A1807 /* juce_FlacAudioFormat.h */,
84F1E70C10403614006A1807 /* juce_OggVorbisAudioFormat.cpp */,
84F1E70610403614006A1807 /* juce_OggVorbisAudioFormat.h */,
84F1E70A10403614006A1807 /* juce_QuickTimeAudioFormat.cpp */,
84F1E70710403614006A1807 /* juce_QuickTimeAudioFormat.h */,
84F1E70910403614006A1807 /* juce_WavAudioFormat.cpp */,
84F1E70810403614006A1807 /* juce_WavAudioFormat.h */,
);
name = audio_file_formats;
path = ../../src/audio/audio_file_formats;

View file

@ -14,7 +14,6 @@
841FE4410E8ABDD4003C3263 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841FE43B0E8ABDD4003C3263 /* WebKit.framework */; };
8450577A0EB52CE500029DFF /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 845057790EB52CE500029DFF /* QuickTime.framework */; };
847F4D900E8AC35C00F64426 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 847F4D8F0E8AC35C00F64426 /* QTKit.framework */; };
847F4EA50E8BA9C300F64426 /* AudioDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9A0E8BA9C300F64426 /* AudioDemo.cpp */; };
847F4EA60E8BA9C300F64426 /* DragAndDropDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9B0E8BA9C300F64426 /* DragAndDropDemo.cpp */; };
847F4EA70E8BA9C300F64426 /* FontsAndTextDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */; };
847F4EA80E8BA9C300F64426 /* InterprocessCommsDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4E9D0E8BA9C300F64426 /* InterprocessCommsDemo.cpp */; };
@ -29,6 +28,12 @@
847F4EB90E8BA9DD00F64426 /* BinaryData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EB10E8BA9DD00F64426 /* BinaryData.cpp */; };
847F4EBA0E8BA9DD00F64426 /* juce_LibrarySource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EB40E8BA9DD00F64426 /* juce_LibrarySource.mm */; };
847F4EBB0E8BA9DD00F64426 /* MainDemoWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F4EB60E8BA9DD00F64426 /* MainDemoWindow.cpp */; };
84913FDE1063947900456AFC /* AudioDemoLatencyPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84913FD41063947900456AFC /* AudioDemoLatencyPage.cpp */; };
84913FDF1063947900456AFC /* AudioDemoPlaybackPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84913FD61063947900456AFC /* AudioDemoPlaybackPage.cpp */; };
84913FE01063947900456AFC /* AudioDemoSetupPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84913FD81063947900456AFC /* AudioDemoSetupPage.cpp */; };
84913FE11063947900456AFC /* AudioDemoSynthPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84913FDA1063947900456AFC /* AudioDemoSynthPage.cpp */; };
84913FE21063947900456AFC /* AudioDemoTabComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84913FDC1063947900456AFC /* AudioDemoTabComponent.cpp */; };
849144091064E54800456AFC /* AudioDemoRecordPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 849144071064E54800456AFC /* AudioDemoRecordPage.cpp */; };
849786F3103560630020003B /* DiscRecording.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 849786F2103560630020003B /* DiscRecording.framework */; };
84E81551100BAF6200FAE212 /* WebBrowserDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E81550100BAF6200FAE212 /* WebBrowserDemo.cpp */; };
84EE00FA0FF22E390093FACA /* CameraDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84EE00F90FF22E390093FACA /* CameraDemo.cpp */; };
@ -46,7 +51,6 @@
841FE43B0E8ABDD4003C3263 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
845057790EB52CE500029DFF /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
847F4D8F0E8AC35C00F64426 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = "<absolute>"; };
847F4E9A0E8BA9C300F64426 /* AudioDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemo.cpp; path = ../../src/demos/AudioDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9B0E8BA9C300F64426 /* DragAndDropDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DragAndDropDemo.cpp; path = ../../src/demos/DragAndDropDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FontsAndTextDemo.cpp; path = ../../src/demos/FontsAndTextDemo.cpp; sourceTree = SOURCE_ROOT; };
847F4E9D0E8BA9C300F64426 /* InterprocessCommsDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InterprocessCommsDemo.cpp; path = ../../src/demos/InterprocessCommsDemo.cpp; sourceTree = SOURCE_ROOT; };
@ -65,6 +69,18 @@
847F4EB50E8BA9DD00F64426 /* jucedemo_headers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jucedemo_headers.h; path = ../../src/jucedemo_headers.h; sourceTree = SOURCE_ROOT; };
847F4EB60E8BA9DD00F64426 /* MainDemoWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MainDemoWindow.cpp; path = ../../src/MainDemoWindow.cpp; sourceTree = SOURCE_ROOT; };
847F4EB70E8BA9DD00F64426 /* MainDemoWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MainDemoWindow.h; path = ../../src/MainDemoWindow.h; sourceTree = SOURCE_ROOT; };
84913FD41063947900456AFC /* AudioDemoLatencyPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoLatencyPage.cpp; path = ../../src/demos/AudioDemoLatencyPage.cpp; sourceTree = SOURCE_ROOT; };
84913FD51063947900456AFC /* AudioDemoLatencyPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoLatencyPage.h; path = ../../src/demos/AudioDemoLatencyPage.h; sourceTree = SOURCE_ROOT; };
84913FD61063947900456AFC /* AudioDemoPlaybackPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoPlaybackPage.cpp; path = ../../src/demos/AudioDemoPlaybackPage.cpp; sourceTree = SOURCE_ROOT; };
84913FD71063947900456AFC /* AudioDemoPlaybackPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoPlaybackPage.h; path = ../../src/demos/AudioDemoPlaybackPage.h; sourceTree = SOURCE_ROOT; };
84913FD81063947900456AFC /* AudioDemoSetupPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoSetupPage.cpp; path = ../../src/demos/AudioDemoSetupPage.cpp; sourceTree = SOURCE_ROOT; };
84913FD91063947900456AFC /* AudioDemoSetupPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoSetupPage.h; path = ../../src/demos/AudioDemoSetupPage.h; sourceTree = SOURCE_ROOT; };
84913FDA1063947900456AFC /* AudioDemoSynthPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoSynthPage.cpp; path = ../../src/demos/AudioDemoSynthPage.cpp; sourceTree = SOURCE_ROOT; };
84913FDB1063947900456AFC /* AudioDemoSynthPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoSynthPage.h; path = ../../src/demos/AudioDemoSynthPage.h; sourceTree = SOURCE_ROOT; };
84913FDC1063947900456AFC /* AudioDemoTabComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoTabComponent.cpp; path = ../../src/demos/AudioDemoTabComponent.cpp; sourceTree = SOURCE_ROOT; };
84913FDD1063947900456AFC /* AudioDemoTabComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoTabComponent.h; path = ../../src/demos/AudioDemoTabComponent.h; sourceTree = SOURCE_ROOT; };
849144071064E54800456AFC /* AudioDemoRecordPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDemoRecordPage.cpp; path = ../../src/demos/AudioDemoRecordPage.cpp; sourceTree = SOURCE_ROOT; };
849144081064E54800456AFC /* AudioDemoRecordPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDemoRecordPage.h; path = ../../src/demos/AudioDemoRecordPage.h; sourceTree = SOURCE_ROOT; };
849786F2103560630020003B /* DiscRecording.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
84E81550100BAF6200FAE212 /* WebBrowserDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; name = WebBrowserDemo.cpp; path = ../../src/demos/WebBrowserDemo.cpp; sourceTree = SOURCE_ROOT; };
84EE00F90FF22E390093FACA /* CameraDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CameraDemo.cpp; path = ../../src/demos/CameraDemo.cpp; sourceTree = SOURCE_ROOT; };
@ -160,7 +176,18 @@
847F4D8A0E8AC27A00F64426 /* demos */ = {
isa = PBXGroup;
children = (
847F4E9A0E8BA9C300F64426 /* AudioDemo.cpp */,
84913FD41063947900456AFC /* AudioDemoLatencyPage.cpp */,
84913FD51063947900456AFC /* AudioDemoLatencyPage.h */,
84913FD61063947900456AFC /* AudioDemoPlaybackPage.cpp */,
84913FD71063947900456AFC /* AudioDemoPlaybackPage.h */,
849144071064E54800456AFC /* AudioDemoRecordPage.cpp */,
849144081064E54800456AFC /* AudioDemoRecordPage.h */,
84913FD81063947900456AFC /* AudioDemoSetupPage.cpp */,
84913FD91063947900456AFC /* AudioDemoSetupPage.h */,
84913FDA1063947900456AFC /* AudioDemoSynthPage.cpp */,
84913FDB1063947900456AFC /* AudioDemoSynthPage.h */,
84913FDC1063947900456AFC /* AudioDemoTabComponent.cpp */,
84913FDD1063947900456AFC /* AudioDemoTabComponent.h */,
84EE00F90FF22E390093FACA /* CameraDemo.cpp */,
847F4E9B0E8BA9C300F64426 /* DragAndDropDemo.cpp */,
847F4E9C0E8BA9C300F64426 /* FontsAndTextDemo.cpp */,
@ -230,7 +257,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
847F4EA50E8BA9C300F64426 /* AudioDemo.cpp in Sources */,
847F4EA60E8BA9C300F64426 /* DragAndDropDemo.cpp in Sources */,
847F4EA70E8BA9C300F64426 /* FontsAndTextDemo.cpp in Sources */,
847F4EA80E8BA9C300F64426 /* InterprocessCommsDemo.cpp in Sources */,
@ -247,6 +273,12 @@
847F4EBB0E8BA9DD00F64426 /* MainDemoWindow.cpp in Sources */,
84EE00FA0FF22E390093FACA /* CameraDemo.cpp in Sources */,
84E81551100BAF6200FAE212 /* WebBrowserDemo.cpp in Sources */,
84913FDE1063947900456AFC /* AudioDemoLatencyPage.cpp in Sources */,
84913FDF1063947900456AFC /* AudioDemoPlaybackPage.cpp in Sources */,
84913FE01063947900456AFC /* AudioDemoSetupPage.cpp in Sources */,
84913FE11063947900456AFC /* AudioDemoSynthPage.cpp in Sources */,
84913FE21063947900456AFC /* AudioDemoTabComponent.cpp in Sources */,
849144091064E54800456AFC /* AudioDemoRecordPage.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -1,470 +1,496 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="jucedemo"
ProjectGUID="{050D65C2-17C4-4EE1-ABCE-BEA9DA83D77A}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/jucedemo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/jucedemo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/jucedemo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../../../juce/bin"
GenerateManifest="false"
IgnoreDefaultLibraryNames=""
ProgramDatabaseFile=".\Release/jucedemo.pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/jucedemo.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/jucedemo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/jucedemo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/jucedemo.exe"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../../../juce/bin"
IgnoreDefaultLibraryNames="libcmt.lib, msvcrt.lib"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/jucedemo.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/jucedemo.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\..\src\ApplicationStartup.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\BinaryData.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\juce_AppConfig.h"
>
</File>
<File
RelativePath="..\..\src\juce_LibrarySource.cpp"
>
</File>
<File
RelativePath="..\..\src\jucedemo_headers.h"
>
</File>
<File
RelativePath="..\..\src\MainDemoWindow.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\MainDemoWindow.h"
>
</File>
<Filter
Name="demos"
>
<File
RelativePath="..\..\src\demos\AudioDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\CameraDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\DragAndDropDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\FontsAndTextDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\InterprocessCommsDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\OpenGLDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\PathsAndTransformsDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\QuickTimeDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\TableDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\ThreadingDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\TreeViewDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\WebBrowserDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\WidgetsDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="jucedemo"
ProjectGUID="{050D65C2-17C4-4EE1-ABCE-BEA9DA83D77A}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/jucedemo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/jucedemo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/jucedemo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../../../juce/bin"
GenerateManifest="false"
IgnoreDefaultLibraryNames=""
ProgramDatabaseFile=".\Release/jucedemo.pdb"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/jucedemo.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/jucedemo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/jucedemo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/jucedemo.exe"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../../../juce/bin"
IgnoreDefaultLibraryNames="libcmt.lib, msvcrt.lib"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/jucedemo.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/jucedemo.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\..\src\ApplicationStartup.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\BinaryData.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\juce_AppConfig.h"
>
</File>
<File
RelativePath="..\..\src\juce_LibrarySource.cpp"
>
</File>
<File
RelativePath="..\..\src\jucedemo_headers.h"
>
</File>
<File
RelativePath="..\..\src\MainDemoWindow.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\MainDemoWindow.h"
>
</File>
<Filter
Name="demos"
>
<File
RelativePath="..\..\src\demos\AudioDemoLatencyPage.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoLatencyPage.h"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoPlaybackPage.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoPlaybackPage.h"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoRecordPage.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoRecordPage.h"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoSetupPage.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoSetupPage.h"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoSynthPage.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoSynthPage.h"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoTabComponent.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\AudioDemoTabComponent.h"
>
</File>
<File
RelativePath="..\..\src\demos\CameraDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\DragAndDropDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\FontsAndTextDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\InterprocessCommsDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\OpenGLDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\PathsAndTransformsDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\QuickTimeDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\TableDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\ThreadingDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\TreeViewDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\demos\WebBrowserDemo.cpp"
>
</File>
<File
RelativePath="..\..\src\demos\WidgetsDemo.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions=""
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

File diff suppressed because it is too large Load diff

View file

@ -5,48 +5,9 @@
namespace BinaryData
{
extern const char* audiodemo_cpp;
const int audiodemo_cppSize = 23377;
extern const char* camerademo_cpp;
const int camerademo_cppSize = 7155;
extern const char* draganddropdemo_cpp;
const int draganddropdemo_cppSize = 7724;
extern const char* fontsandtextdemo_cpp;
const int fontsandtextdemo_cppSize = 8851;
extern const char* interprocesscommsdemo_cpp;
const int interprocesscommsdemo_cppSize = 12418;
extern const char* opengldemo_cpp;
const int opengldemo_cppSize = 9362;
extern const char* pathsandtransformsdemo_cpp;
const int pathsandtransformsdemo_cppSize = 14018;
extern const char* quicktimedemo_cpp;
const int quicktimedemo_cppSize = 4363;
extern const char* readme__what_this_directory_is_for_txt;
const int readme__what_this_directory_is_for_txtSize = 259;
extern const char* tabledemo_cpp;
const int tabledemo_cppSize = 12168;
extern const char* threadingdemo_cpp;
const int threadingdemo_cppSize = 10271;
extern const char* treeviewdemo_cpp;
const int treeviewdemo_cppSize = 8502;
extern const char* webbrowserdemo_cpp;
const int webbrowserdemo_cppSize = 5195;
extern const char* widgetsdemo_cpp;
const int widgetsdemo_cppSize = 53176;
extern const char* cello_wav;
const int cello_wavSize = 46348;

View file

@ -27,57 +27,6 @@
#include "MainDemoWindow.h"
//==============================================================================
class SourceCodeWindow;
static SourceCodeWindow* sourceWindow = 0;
//==============================================================================
class SourceCodeWindow : public DialogWindow
{
TextEditor* textBox;
public:
SourceCodeWindow()
: DialogWindow (T("JUCE Demo Source Code!"),
Colours::floralwhite,
false)
{
setContentComponent (textBox = new TextEditor());
textBox->setColour (TextEditor::backgroundColourId, Colours::white);
textBox->setMultiLine (true, false);
textBox->setReturnKeyStartsNewLine (true);
setResizable (true, true); // we'll choose a corner-resizer component for this window,
// as a contrast to the resizable border on the main window
}
~SourceCodeWindow()
{
// the text editor gets deleted automatically because it's the
// window's content component.
sourceWindow = 0;
}
void closeButtonPressed()
{
delete this;
}
void updateSourceCode (const String& text)
{
Font font (14.0f);
font.setTypefaceName (Font::getDefaultMonospacedFontName());
textBox->setFont (font);
textBox->setText (text);
toFront (true);
}
};
//==============================================================================
class ContentComp : public Component,
public MenuBarModel,
@ -90,7 +39,6 @@ class ContentComp : public Component,
Component* currentDemo;
int currentDemoId;
const char* demoSourceCodeText;
TooltipWindow tooltipWindow; // to add tooltips to an application, you
// just need to create one of these and leave it
@ -112,8 +60,6 @@ class ContentComp : public Component,
showCamera = 0x2011,
showWebBrowser = 0x2012,
showSourceCode = 0x200a,
setDefaultLookAndFeel = 0x200b,
setOldSchoolLookAndFeel = 0x200c,
useNativeTitleBar = 0x200d,
@ -126,8 +72,7 @@ public:
ContentComp (MainDemoWindow* mainWindow_)
: mainWindow (mainWindow_),
currentDemo (0),
currentDemoId (0),
demoSourceCodeText (0)
currentDemoId (0)
{
invokeDirectly (showPathsAndTransforms, true);
}
@ -139,8 +84,6 @@ public:
LookAndFeel::setDefaultLookAndFeel (0);
deleteAllChildren();
deleteAndZero (sourceWindow);
}
//==============================================================================
@ -151,33 +94,19 @@ public:
}
//==============================================================================
void showDemo (Component* demoComp, const char* sourceCodeText)
void showDemo (Component* demoComp)
{
delete currentDemo;
currentDemo = demoComp;
addAndMakeVisible (currentDemo);
resized();
demoSourceCodeText = sourceCodeText;
}
void showSource()
{
if (sourceWindow == 0)
{
sourceWindow = new SourceCodeWindow();
sourceWindow->centreAroundComponent (this, 750, 600);
sourceWindow->setVisible (true);
}
sourceWindow->updateSourceCode (demoSourceCodeText);
}
//==============================================================================
const StringArray getMenuBarNames()
{
const tchar* const names[] = { T("Demo"), T("Source Code"), T("Look-and-feel"), 0 };
const tchar* const names[] = { T("Demo"), T("Look-and-feel"), 0 };
return StringArray ((const tchar**) names);
}
@ -209,10 +138,6 @@ public:
menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
}
else if (menuIndex == 1)
{
menu.addCommandItem (commandManager, showSourceCode);
}
else if (menuIndex == 2)
{
menu.addCommandItem (commandManager, setDefaultLookAndFeel);
menu.addCommandItem (commandManager, setOldSchoolLookAndFeel);
@ -266,7 +191,6 @@ public:
showCamera,
showWebBrowser,
showInterprocessComms,
showSourceCode,
setDefaultLookAndFeel,
setOldSchoolLookAndFeel,
useNativeTitleBar
@ -381,11 +305,6 @@ public:
result.setTicked (currentDemoId == showInterprocessComms);
break;
case showSourceCode:
result.setInfo (T("Show the source code for this demo"), T("Opens a window containing this demo's source code"), generalCategory, 0);
result.addDefaultKeypress (T('s'), ModifierKeys::commandModifier);
break;
case setDefaultLookAndFeel:
result.setInfo (T("Use default look-and-feel"), String::empty, generalCategory, 0);
result.setTicked ((typeid (LookAndFeel) == typeid (getLookAndFeel())) != 0);
@ -426,82 +345,78 @@ public:
switch (info.commandID)
{
case showPathsAndTransforms:
showDemo (createPathsAndTransformsDemo(), BinaryData::pathsandtransformsdemo_cpp);
showDemo (createPathsAndTransformsDemo());
currentDemoId = showPathsAndTransforms;
break;
case showFontsAndText:
showDemo (createFontsAndTextDemo(), BinaryData::fontsandtextdemo_cpp);
showDemo (createFontsAndTextDemo());
currentDemoId = showFontsAndText;
break;
case showWidgets:
showDemo (createWidgetsDemo (mainWindow->commandManager), BinaryData::widgetsdemo_cpp);
showDemo (createWidgetsDemo (mainWindow->commandManager));
currentDemoId = showWidgets;
break;
case showThreading:
showDemo (createThreadingDemo(), BinaryData::threadingdemo_cpp);
showDemo (createThreadingDemo());
currentDemoId = showThreading;
break;
case showTreeView:
showDemo (createTreeViewDemo(), BinaryData::treeviewdemo_cpp);
showDemo (createTreeViewDemo());
currentDemoId = showTreeView;
break;
case showTable:
showDemo (createTableDemo(), BinaryData::tabledemo_cpp);
showDemo (createTableDemo());
currentDemoId = showTable;
break;
case showAudio:
showDemo (createAudioDemo(), BinaryData::audiodemo_cpp);
showDemo (createAudioDemo());
currentDemoId = showAudio;
break;
case showDragAndDrop:
showDemo (createDragAndDropDemo(), BinaryData::draganddropdemo_cpp);
showDemo (createDragAndDropDemo());
currentDemoId = showDragAndDrop;
break;
case showOpenGL:
#if JUCE_OPENGL
showDemo (createOpenGLDemo(), BinaryData::opengldemo_cpp);
showDemo (createOpenGLDemo());
currentDemoId = showOpenGL;
#endif
break;
case showQuicktime:
#if JUCE_QUICKTIME && ! JUCE_LINUX
showDemo (createQuickTimeDemo(), BinaryData::quicktimedemo_cpp);
showDemo (createQuickTimeDemo());
currentDemoId = showQuicktime;
#endif
break;
case showCamera:
#if JUCE_USE_CAMERA
showDemo (createCameraDemo(), BinaryData::camerademo_cpp);
showDemo (createCameraDemo());
currentDemoId = showCamera;
#endif
break;
case showWebBrowser:
#if JUCE_WEB_BROWSER
showDemo (createWebBrowserDemo(), BinaryData::webbrowserdemo_cpp);
showDemo (createWebBrowserDemo());
currentDemoId = showWebBrowser;
#endif
break;
case showInterprocessComms:
showDemo (createInterprocessCommsDemo(), BinaryData::interprocesscommsdemo_cpp);
showDemo (createInterprocessCommsDemo());
currentDemoId = showInterprocessComms;
break;
case showSourceCode:
showSource();
break;
case setDefaultLookAndFeel:
LookAndFeel::setDefaultLookAndFeel (0);
break;

View file

@ -1,637 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
/** Our demo synth only has one type of sound, and it's very basic..
*/
class SineWaveSound : public SynthesiserSound
{
public:
SineWaveSound (const BitArray& midiNotes_)
: midiNotes (midiNotes_)
{
}
bool appliesToNote (const int midiNoteNumber)
{
return midiNotes [midiNoteNumber];
}
bool appliesToChannel (const int midiChannel) { return true; }
private:
// this will contain the notes that this sound is attached to.
BitArray midiNotes;
};
//==============================================================================
/** Our demo synth voice just plays a sine wave..
*/
class SineWaveVoice : public SynthesiserVoice
{
public:
SineWaveVoice()
: angleDelta (0.0),
tailOff (0.0)
{
}
bool canPlaySound (SynthesiserSound* sound)
{
return dynamic_cast <SineWaveSound*> (sound) != 0;
}
void startNote (const int midiNoteNumber, const float velocity,
SynthesiserSound* sound, const int currentPitchWheelPosition)
{
currentAngle = 0.0;
level = velocity * 0.15;
tailOff = 0.0;
double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
double cyclesPerSample = cyclesPerSecond / getSampleRate();
angleDelta = cyclesPerSample * 2.0 * double_Pi;
}
void stopNote (const bool allowTailOff)
{
if (allowTailOff)
{
// start a tail-off by setting this flag. The render callback will pick up on
// this and do a fade out, calling clearCurrentNote() when it's finished.
if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
// stopNote method could be called more than once.
tailOff = 1.0;
}
else
{
// we're being told to stop playing immediately, so reset everything..
clearCurrentNote();
angleDelta = 0.0;
}
}
void pitchWheelMoved (const int newValue)
{
// can't be bothered implementing this for the demo!
}
void controllerMoved (const int controllerNumber, const int newValue)
{
// not interested in controllers in this case.
}
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (angleDelta != 0.0)
{
if (tailOff > 0)
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level * tailOff);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
tailOff *= 0.99;
if (tailOff <= 0.005)
{
clearCurrentNote();
angleDelta = 0.0;
break;
}
}
}
else
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
}
}
}
}
private:
double currentAngle, angleDelta, level, tailOff;
};
//==============================================================================
/** This is an audio source that streams the output of our demo synth.
*/
class SynthAudioSource : public AudioSource
{
public:
//==============================================================================
// this collects real-time midi messages from the midi input device, and
// turns them into blocks that we can process in our audio callback
MidiMessageCollector midiCollector;
// this represents the state of which keys on our on-screen keyboard are held
// down. When the mouse is clicked on the keyboard component, this object also
// generates midi messages for this, which we can pass on to our synth.
MidiKeyboardState keyboardState;
// the synth itself!
Synthesiser synth;
//==============================================================================
SynthAudioSource()
{
// we'll be mixing two different types of sound, so here we'll create two
// sets of note maps, putting each sound on a different octave of the keyboard:
BitArray sinewaveNotes, samplerNotes;
int i;
for (i = 0; i < 128; ++i)
{
if (((i / 12) & 1) != 0)
sinewaveNotes.setBit (i);
else
samplerNotes.setBit (i);
}
// add a wave sound, which will get applied to some of the notes..
synth.addSound (new SineWaveSound (sinewaveNotes));
// give our synth a few voices that can play the wave sound..
for (i = 4; --i >= 0;)
synth.addVoice (new SineWaveVoice());
WavAudioFormat wavFormat;
AudioFormatReader* audioReader
= wavFormat.createReaderFor (new MemoryInputStream (BinaryData::cello_wav,
BinaryData::cello_wavSize,
false),
true);
synth.addSound (new SamplerSound (T("demo sound"),
*audioReader,
samplerNotes,
74, // root midi note
0.1, // attack time
0.1, // release time
10.0 // maximum sample length
));
delete audioReader;
// and give the synth some sampler voices to play the sampled sound..
for (i = 4; --i >= 0;)
synth.addVoice (new SamplerVoice());
}
void prepareToPlay (int samplesPerBlockExpected,
double sampleRate)
{
midiCollector.reset (sampleRate);
synth.setCurrentPlaybackSampleRate (sampleRate);
}
void releaseResources()
{
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
// the synth always adds its output to the audio buffer, so we have to clear it
// first..
bufferToFill.clearActiveBufferRegion();
// fill a midi buffer with incoming messages from the midi input.
MidiBuffer incomingMidi;
midiCollector.removeNextBlockOfMessages (incomingMidi, bufferToFill.numSamples);
// pass these messages to the keyboard state so that it can update the component
// to show on-screen which keys are being pressed on the physical midi keyboard.
// This call will also add midi messages to the buffer which were generated by
// the mouse-clicking on the on-screen keyboard.
keyboardState.processNextMidiBuffer (incomingMidi, 0, bufferToFill.numSamples, true);
// and now get the synth to process the midi events and generate its output.
synth.renderNextBlock (*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}
};
//==============================================================================
class AudioInputWaveformDisplay : public Component,
public Timer,
public AudioIODeviceCallback
{
public:
AudioInputWaveformDisplay()
{
bufferPos = 0;
bufferSize = 2048;
circularBuffer = (float*) juce_calloc (sizeof (float) * bufferSize);
currentInputLevel = 0.0f;
numSamplesIn = 0;
setOpaque (true);
startTimer (1000 / 50); // repaint every 1/50 of a second
}
~AudioInputWaveformDisplay()
{
juce_free (circularBuffer);
}
void paint (Graphics& g)
{
g.fillAll (Colours::black);
g.setColour (Colours::lightgreen);
const float halfHeight = getHeight() * 0.5f;
int bp = bufferPos;
for (int x = getWidth(); --x >= 0;)
{
const int samplesAgo = getWidth() - x;
const float level = circularBuffer [(bp + bufferSize - samplesAgo) % bufferSize];
if (level > 0.01f)
g.drawLine ((float) x, halfHeight - halfHeight * level,
(float) x, halfHeight + halfHeight * level);
}
}
void timerCallback()
{
repaint();
}
void addSample (const float sample)
{
currentInputLevel += fabsf (sample);
const int samplesToAverage = 128;
if (++numSamplesIn > samplesToAverage)
{
circularBuffer [bufferPos++ % bufferSize] = currentInputLevel / samplesToAverage;
numSamplesIn = 0;
currentInputLevel = 0.0f;
}
}
void audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
for (int i = 0; i < totalNumInputChannels; ++i)
{
if (inputChannelData [i] != 0)
{
for (int j = 0; j < numSamples; ++j)
addSample (inputChannelData [i][j]);
break;
}
}
}
void audioDeviceAboutToStart (AudioIODevice*)
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
void audioDeviceStopped()
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
private:
float* circularBuffer;
float currentInputLevel;
int volatile bufferPos, bufferSize, numSamplesIn;
};
//==============================================================================
class AudioDemo : public Component,
public FilenameComponentListener,
public ButtonListener,
public ChangeListener,
public AudioIODeviceCallback
{
//==============================================================================
FilenameComponent* fileChooser;
TextButton* playButton;
TextButton* stopButton;
TextButton* audioSettingsButton;
MidiKeyboardComponent* keyboardComponent;
AudioInputWaveformDisplay* waveformComponent;
//==============================================================================
// this wraps the actual audio device
AudioDeviceManager audioDeviceManager;
// this allows an audio source to be streamed to the IO device
AudioSourcePlayer audioSourcePlayer;
// this controls the playback of a positionable audio stream, handling the
// starting/stopping and sample-rate conversion
AudioTransportSource transportSource;
// this source contains our synth, and generates its output
SynthAudioSource synthSource;
// this source is used to mix together the output from our synth source
// and wave player source
MixerAudioSource mixerSource;
// this is the actual stream that's going to read from the audio file.
AudioFormatReaderSource* currentAudioFileSource;
File currentFile;
public:
//==============================================================================
AudioDemo()
{
setName (T("Audio"));
currentAudioFileSource = 0;
//==============================================================================
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
addAndMakeVisible (fileChooser = new FilenameComponent (T("audiofile"),
File::nonexistent,
true, false, false,
formatManager.getWildcardForAllFormats(),
String::empty,
T("(choose a WAV or AIFF file to play)")));
fileChooser->addListener (this);
fileChooser->setBrowseButtonText (T("browse"));
addAndMakeVisible (playButton = new TextButton (T("play"),
T("click here to play the current audio file")));
playButton->addButtonListener (this);
playButton->setColour (TextButton::buttonColourId, Colours::lightgreen);
playButton->setColour (TextButton::buttonOnColourId, Colours::lightgreen);
playButton->setConnectedEdges (Button::ConnectedOnRight);
addAndMakeVisible (stopButton = new TextButton (T("stop"),
T("click here to play the current audio file")));
stopButton->addButtonListener (this);
stopButton->setColour (TextButton::buttonColourId, Colours::red);
stopButton->setColour (TextButton::buttonOnColourId, Colours::red);
stopButton->setConnectedEdges (Button::ConnectedOnLeft);
addAndMakeVisible (audioSettingsButton = new TextButton (T("show audio settings..."),
T("click here to change the audio device settings")));
audioSettingsButton->addButtonListener (this);
addAndMakeVisible (keyboardComponent = new MidiKeyboardComponent (synthSource.keyboardState,
MidiKeyboardComponent::horizontalKeyboard));
addAndMakeVisible (waveformComponent = new AudioInputWaveformDisplay());
//==============================================================================
// register for start/stop messages from the transport source..
transportSource.addChangeListener (this);
// and initialise the device manager with no settings so that it picks a
// default device to use.
const String error (audioDeviceManager.initialise (1, /* number of input channels */
2, /* number of output channels */
0, /* no XML settings.. */
true /* select default device on failure */));
if (error.isNotEmpty())
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Audio Demo"),
T("Couldn't open an output device!\n\n") + error);
}
else
{
// add the two audio sources to our mixer..
mixerSource.addInputSource (&transportSource, false);
mixerSource.addInputSource (&synthSource, false);
// ..and connect the mixer to our source player.
audioSourcePlayer.setSource (&mixerSource);
// start the IO device pulling its data from our callback..
audioDeviceManager.addAudioCallback (this);
// and we need to send midi input to our synth for processing
audioDeviceManager.addMidiInputCallback (String::empty, &synthSource.midiCollector);
}
}
~AudioDemo()
{
audioDeviceManager.removeMidiInputCallback (String::empty, &synthSource.midiCollector);
audioDeviceManager.removeAudioCallback (this);
transportSource.removeChangeListener (this);
transportSource.setSource (0);
deleteAndZero (currentAudioFileSource);
audioSourcePlayer.setSource (0);
deleteAllChildren();
}
//==============================================================================
void audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
// pass the audio callback on to our player source, and also the waveform display comp
audioSourcePlayer.audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
}
void audioDeviceAboutToStart (AudioIODevice* device)
{
audioSourcePlayer.audioDeviceAboutToStart (device);
waveformComponent->audioDeviceAboutToStart (device);
}
void audioDeviceStopped()
{
audioSourcePlayer.audioDeviceStopped();
waveformComponent->audioDeviceStopped();
}
//==============================================================================
void paint (Graphics& g)
{
// print some text to explain what state we're in.
g.setColour (Colours::black);
g.setFont (14.0f);
String s;
if (transportSource.isPlaying())
s = T("playing");
else
s = T("stopped");
if (currentAudioFileSource == 0)
s += T(" - no source file selected");
else
s += T(" - file: \"") + currentFile.getFullPathName() + T("\"");
g.drawText (s, 250, 50, getWidth() - 250, 24, Justification::centredLeft, true);
}
void resized()
{
fileChooser->setBounds (10, 10, getWidth() - 20, 24);
playButton->setBounds (10, 50, 100, 24);
stopButton->setBounds (110, 50, 100, 24);
audioSettingsButton->setBounds (10, 120, 200, 24);
audioSettingsButton->changeWidthToFitText();
keyboardComponent->setBounds (10, 200, getWidth() - 20, 60);
waveformComponent->setBounds (10, 300, 400, 80);
updateButtons();
}
void updateButtons()
{
playButton->setEnabled (currentAudioFileSource != 0 && ! transportSource.isPlaying());
stopButton->setEnabled (transportSource.isPlaying());
repaint();
}
void buttonClicked (Button* button)
{
if (button == playButton)
{
transportSource.setPosition (0.0);
transportSource.start();
}
else if (button == stopButton)
{
transportSource.stop();
}
else if (button == audioSettingsButton)
{
// Create an AudioDeviceSelectorComponent which contains the audio choice widgets...
AudioDeviceSelectorComponent audioSettingsComp (audioDeviceManager,
0, 1,
2, 2,
true,
false,
true,
false);
// ...and show it in a DialogWindow...
audioSettingsComp.setSize (500, 450);
DialogWindow::showModalDialog (T("Audio Settings"),
&audioSettingsComp,
this,
Colours::azure,
true);
}
}
void filenameComponentChanged (FilenameComponent*)
{
// this is called when the user changes the filename in the file chooser box
File audioFile (fileChooser->getCurrentFile());
// unload the previous file source and delete it..
transportSource.stop();
transportSource.setSource (0);
deleteAndZero (currentAudioFileSource);
// create a new file source from the file..
// get a format manager and set it up with the basic types (wav and aiff).
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
AudioFormatReader* reader = formatManager.createReaderFor (audioFile);
if (reader != 0)
{
currentFile = audioFile;
currentAudioFileSource = new AudioFormatReaderSource (reader, true);
// ..and plug it into our transport source
transportSource.setSource (currentAudioFileSource,
32768, // tells it to buffer this many samples ahead
reader->sampleRate);
}
updateButtons();
}
void changeListenerCallback (void*)
{
// callback from the transport source to tell us that play has
// started or stopped, so update our buttons..
updateButtons();
}
};
//==============================================================================
Component* createAudioDemo()
{
return new AudioDemo();
}

View file

@ -1,198 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
#if JUCE_USE_CAMERA
//==============================================================================
class CameraDemo : public Component,
public ComboBoxListener,
public ButtonListener,
public CameraImageListener
{
public:
//==============================================================================
CameraDemo()
{
setName (T("Camera"));
cameraDevice = 0;
cameraPreviewComp = 0;
lastSnapshot = 0;
recordingMovie = false;
addAndMakeVisible (cameraSelectorComboBox = new ComboBox (T("Camera")));
createListOfCameras();
cameraSelectorComboBox->setSelectedId (1);
cameraSelectorComboBox->addListener (this);
addAndMakeVisible (snapshotButton = new TextButton (T("Take a snapshot")));
snapshotButton->addButtonListener (this);
snapshotButton->setEnabled (false);
addAndMakeVisible (recordMovieButton = new TextButton (T("Record a movie file (to your desktop)...")));
recordMovieButton->addButtonListener (this);
recordMovieButton->setEnabled (false);
cameraSelectorComboBox->setSelectedId (2);
}
~CameraDemo()
{
deleteAllChildren();
delete cameraDevice;
delete lastSnapshot;
}
void paint (Graphics& g)
{
if (lastSnapshot != 0)
g.drawImageWithin (lastSnapshot,
getWidth() / 2 + 10, 40,
getWidth() / 2 - 20, getHeight() - 50,
RectanglePlacement::centred, false);
}
void resized()
{
cameraSelectorComboBox->setBounds (10, 4, 250, 24);
snapshotButton->changeWidthToFitText (24);
snapshotButton->setTopLeftPosition (cameraSelectorComboBox->getRight() + 20, 4);
recordMovieButton->changeWidthToFitText (24);
recordMovieButton->setTopLeftPosition (snapshotButton->getRight() + 20, 4);
if (cameraPreviewComp != 0)
cameraPreviewComp->setBounds (10, 40, getWidth() / 2 - 20, getHeight() - 50);
}
void comboBoxChanged (ComboBox*)
{
// This is called when the user chooses a camera from the drop-down list.
deleteAndZero (cameraDevice);
deleteAndZero (cameraPreviewComp);
recordingMovie = false;
if (cameraSelectorComboBox->getSelectedId() > 1)
{
// Try to open the user's choice of camera..
cameraDevice = CameraDevice::openDevice (cameraSelectorComboBox->getSelectedId() - 2);
// and if it worked, create a preview component for it..
if (cameraDevice != 0)
addAndMakeVisible (cameraPreviewComp = cameraDevice->createViewerComponent());
}
snapshotButton->setEnabled (cameraDevice != 0);
recordMovieButton->setEnabled (cameraDevice != 0);
resized();
}
void createListOfCameras()
{
cameraSelectorComboBox->clear();
cameraSelectorComboBox->addItem ("No camera", 1);
cameraSelectorComboBox->addSeparator();
StringArray cameras = CameraDevice::getAvailableDevices();
for (int i = 0; i < cameras.size(); ++i)
cameraSelectorComboBox->addItem (cameras[i], i + 2);
}
void buttonClicked (Button* b)
{
if (cameraDevice != 0)
{
if (b == recordMovieButton)
{
// The user has clicked the record movie button..
if (! recordingMovie)
{
// Start recording to a file on the user's desktop..
recordingMovie = true;
File file (File::getSpecialLocation (File::userDesktopDirectory)
.getNonexistentChildFile (T("JuceCameraDemo"),
CameraDevice::getFileExtension()));
cameraDevice->startRecordingToFile (file);
recordMovieButton->setButtonText (T("Stop Recording"));
}
else
{
// Already recording, so stop...
recordingMovie = false;
cameraDevice->stopRecording();
recordMovieButton->setButtonText (T("Start recording (to a file on your desktop)"));
}
}
else
{
// When the user clicks the snapshot button, we'll attach ourselves to
// the camera as a listener, and wait for an image to arrive...
cameraDevice->addListener (this);
}
}
}
// This is called by the camera device when a new image arrives
void imageReceived (Image& image)
{
// In this app we just want to take one image, so as soon as this happens,
// we'll unregister ourselves as a listener.
if (cameraDevice != 0)
cameraDevice->removeListener (this);
// This callback won't be on the message thread, so need to lock it before using
// data that may already be in use..
const MessageManagerLock mm;
deleteAndZero (lastSnapshot);
lastSnapshot = image.createCopy();
repaint();
}
private:
//==============================================================================
CameraDevice* cameraDevice;
ComboBox* cameraSelectorComboBox;
TextButton* snapshotButton;
TextButton* recordMovieButton;
Component* cameraPreviewComp;
bool recordingMovie;
Image* lastSnapshot;
};
//==============================================================================
Component* createCameraDemo()
{
return new CameraDemo();
}
#endif

View file

@ -1,234 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
// this is the listbox containing the draggable source components..
class DragAndDropDemoSource : public ListBox,
public ListBoxModel
{
public:
//==============================================================================
DragAndDropDemoSource()
: ListBox (T("d+d source"), 0)
{
// tells the ListBox that this object supplies the info about
// its rows.
setModel (this);
setMultipleSelectionEnabled (true);
}
~DragAndDropDemoSource()
{
}
//==============================================================================
// The following methods implement the necessary virtual functions from ListBoxModel,
// telling the listbox how many rows there are, painting them, etc.
int getNumRows()
{
return 30;
}
void paintListBoxItem (int rowNumber,
Graphics& g,
int width, int height,
bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (Colours::lightblue);
g.setColour (Colours::black);
g.setFont (height * 0.7f);
g.drawText (T("Row Number ") + String (rowNumber + 1),
5, 0, width, height,
Justification::centredLeft, true);
}
const String getDragSourceDescription (const SparseSet<int>& selectedRows)
{
// for our drag desctription, we'll just make a list of the selected
// row numbers - this will be picked up by the drag target and displayed in
// its box.
String desc;
for (int i = 0; i < selectedRows.size(); ++i)
desc << (selectedRows [i] + 1) << T(" ");
return desc.trim();
}
//==============================================================================
// this just fills in the background of the listbox
void paint (Graphics& g)
{
g.fillAll (Colours::white.withAlpha (0.7f));
}
/*void listBoxItemClicked (int row, const MouseEvent& e)
{
PopupMenu m;
m.addItem (1, "sdfsdfs");
m.show();
//AlertWindow::showMessageBox (AlertWindow::InfoIcon, "asdfsadfads", "srdfsdfa");
DocumentWindow* dw = new DocumentWindow ("sfdsd", Colours::white, DocumentWindow::allButtons, true);
dw->setBounds (100, 100, 500, 500);
dw->setVisible (true);
}*/
};
//==============================================================================
// and this is a component that can have things dropped onto it..
class DragAndDropDemoTarget : public Component,
public DragAndDropTarget
{
bool somethingIsBeingDraggedOver;
String message;
public:
//==============================================================================
DragAndDropDemoTarget()
{
somethingIsBeingDraggedOver = false;
message = T("Drag-and-drop some rows from the top-left box onto this component!");
}
~DragAndDropDemoTarget()
{
}
//==============================================================================
void paint (Graphics& g)
{
g.fillAll (Colours::green.withAlpha (0.2f));
// draw a red line around the comp if the user's currently dragging something over it..
if (somethingIsBeingDraggedOver)
{
g.setColour (Colours::red);
g.drawRect (0, 0, getWidth(), getHeight(), 3);
}
g.setColour (Colours::black);
g.setFont (14.0f);
g.drawFittedText (message, 10, 0, getWidth() - 20, getHeight(), Justification::centred, 4);
}
//==============================================================================
bool isInterestedInDragSource (const String& sourceDescription,
Component* sourceComponent)
{
// normally you'd check the sourceDescription value to see if it's the
// sort of object that you're interested in before returning true, but for
// the demo, we'll say yes to anything..
return true;
}
void itemDragEnter (const String& sourceDescription,
Component* sourceComponent,
int x, int y)
{
somethingIsBeingDraggedOver = true;
repaint();
}
void itemDragMove (const String& sourceDescription,
Component* sourceComponent,
int x, int y)
{
}
void itemDragExit (const String& sourceDescription,
Component* sourceComponent)
{
somethingIsBeingDraggedOver = false;
repaint();
}
void itemDropped (const String& sourceDescription,
Component* sourceComponent,
int x, int y)
{
message = T("last rows dropped: ") + sourceDescription;
somethingIsBeingDraggedOver = false;
repaint();
}
};
//==============================================================================
class DragAndDropDemo : public Component,
public DragAndDropContainer
{
//==============================================================================
DragAndDropDemoSource* source;
DragAndDropDemoTarget* target;
public:
//==============================================================================
DragAndDropDemo()
{
setName (T("Drag-and-Drop"));
source = new DragAndDropDemoSource();
addAndMakeVisible (source);
target = new DragAndDropDemoTarget();
addAndMakeVisible (target);
}
~DragAndDropDemo()
{
deleteAllChildren();
}
void resized()
{
source->setBounds (10, 10, 250, 150);
target->setBounds (getWidth() - 260, getHeight() - 160, 250, 150);
}
//==============================================================================
// (need to put this in to disambiguate the new/delete operators used in the
// two base classes).
juce_UseDebuggingNewOperator
};
//==============================================================================
Component* createDragAndDropDemo()
{
return new DragAndDropDemo();
}

View file

@ -1,209 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
class FontsAndTextDemo : public Component,
public ListBoxModel,
public ButtonListener,
public SliderListener
{
OwnedArray <Font> fonts;
ListBox* listBox;
TextEditor* textBox;
ToggleButton* boldButton;
ToggleButton* italicButton;
Slider* sizeSlider;
StretchableLayoutManager verticalLayout;
StretchableLayoutManager horizontalLayout;
StretchableLayoutResizerBar* verticalDividerBar;
StretchableLayoutResizerBar* horizontalDividerBar;
public:
//==============================================================================
FontsAndTextDemo()
{
setName (T("Fonts"));
Font::findFonts (fonts);
addAndMakeVisible (listBox = new ListBox (T("fonts"), this));
listBox->setRowHeight (28);
addAndMakeVisible (textBox = new TextEditor());
textBox->setColour (TextEditor::backgroundColourId, Colours::white);
textBox->setColour (TextEditor::outlineColourId, Colours::black.withAlpha (0.5f));
textBox->setMultiLine (true, true);
textBox->setReturnKeyStartsNewLine (true);
textBox->setText (T("The Quick Brown Fox Jumped Over The Lazy Dog\n\nAa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789"));
addAndMakeVisible (boldButton = new ToggleButton (T("bold")));
boldButton->addButtonListener (this);
addAndMakeVisible (italicButton = new ToggleButton (T("italic")));
italicButton->addButtonListener (this);
addAndMakeVisible (sizeSlider = new Slider (T("size")));
sizeSlider->setRange (3.0, 150.0, 0.1);
sizeSlider->setValue (20.0);
sizeSlider->addListener (this);
listBox->selectRow (0);
listBox->setColour (ListBox::outlineColourId, Colours::black.withAlpha (0.5f));
listBox->setOutlineThickness (1);
// set up the layout and resizer bars..
verticalLayout.setItemLayout (0, -0.2, -0.8, -0.5); // width of the font list must be
// between 20% and 80%, preferably 50%
verticalLayout.setItemLayout (1, 8, 8, 8); // the vertical divider drag-bar thing is always 8 pixels wide
verticalLayout.setItemLayout (2, 150, -1.0, -0.5); // the components on the right must be
// at least 150 pixels wide, preferably 50% of the total width
verticalDividerBar = new StretchableLayoutResizerBar (&verticalLayout, 1, true);
addAndMakeVisible (verticalDividerBar);
horizontalLayout.setItemLayout (0, -0.2, -1.0, -0.4); // height of the font text box must be
// between 20% and 100%, preferably 40%
horizontalLayout.setItemLayout (1, 8, 8, 8); // the horizontal divider drag-bar thing is always 8 pixels high
horizontalLayout.setItemLayout (2, 2, 5, 5); // a gap between the controls
horizontalLayout.setItemLayout (3, 15, 20, 20); // the italic button would like to be 20 pixels high
horizontalLayout.setItemLayout (4, 2, 5, 5); // a gap between the controls
horizontalLayout.setItemLayout (5, 15, 20, 20); // the bold button would like to be 20 pixels high
horizontalLayout.setItemLayout (6, 2, 5, 5); // a gap between the controls
horizontalLayout.setItemLayout (7, 15, 20, 20); // the italic button would like to be 20 pixels high
horizontalLayout.setItemLayout (8, 2, 5, 5); // a gap between the controls
horizontalLayout.setItemLayout (9, 15, 20, 20); // the copy code button would like to be 20 pixels high
horizontalLayout.setItemLayout (10, 5, -1.0, 5); // add a gap at the bottom that will fill up any
// space left over - this will stop the
// sliders from always sticking to the
// bottom of the window
horizontalDividerBar = new StretchableLayoutResizerBar (&horizontalLayout, 1, false);
addAndMakeVisible (horizontalDividerBar);
}
~FontsAndTextDemo()
{
deleteAllChildren();
}
void resized()
{
// lay out the list box and vertical divider..
Component* vcomps[] = { listBox, verticalDividerBar, 0 };
verticalLayout.layOutComponents (vcomps, 3,
4, 4, getWidth() - 8, getHeight() - 8,
false, // lay out side-by-side
true); // resize the components' heights as well as widths
// now lay out the text box and the controls below it..
Component* hcomps[] = { textBox, horizontalDividerBar, 0,
boldButton, 0,
italicButton, 0,
sizeSlider };
horizontalLayout.layOutComponents (hcomps, 8,
4 + verticalLayout.getItemCurrentPosition (2), // for their widths, refer to the vertical layout state
4,
verticalLayout.getItemCurrentAbsoluteSize (2),
getHeight() - 8,
true, // lay out above each other
true); // resize the components' widths as well as heights
}
// implements the ListBoxModel method
int getNumRows()
{
return fonts.size();
}
// implements the ListBoxModel method
void paintListBoxItem (int rowNumber,
Graphics& g,
int width, int height,
bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (Colours::lightblue);
if (fonts [rowNumber] != 0)
{
Font font (*fonts [rowNumber]);
font.setHeight (height * 0.7f);
g.setFont (font);
g.drawText (font.getTypefaceName(),
4, 0, width - 4, height,
Justification::centredLeft, true);
}
}
void updatePreviewBoxText()
{
Font* f = fonts [listBox->getSelectedRow()];
if (f != 0)
{
Font font (*f);
font.setHeight ((float) sizeSlider->getValue());
font.setBold (boldButton->getToggleState());
font.setItalic (italicButton->getToggleState());
textBox->applyFontToAllText (font);
}
}
void selectedRowsChanged (int lastRowselected)
{
updatePreviewBoxText();
}
void buttonClicked (Button* button)
{
updatePreviewBoxText();
}
void sliderValueChanged (Slider*)
{
// (this is called when the size slider is moved)
updatePreviewBoxText();
}
};
//==============================================================================
Component* createFontsAndTextDemo()
{
return new FontsAndTextDemo();
}

View file

@ -1,328 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
class InterprocessCommsDemo : public Component,
public ButtonListener,
public ComboBoxListener
{
public:
//==============================================================================
InterprocessCommsDemo()
{
server = new DemoInterprocessConnectionServer (*this);
setName (T("Interprocess Communication"));
// create all our UI bits and pieces..
addAndMakeVisible (modeSelector = new ComboBox (T("mode:")));
modeSelector->setBounds (100, 25, 200, 24);
(new Label (modeSelector->getName(), modeSelector->getName()))->attachToComponent (modeSelector, true);
modeSelector->addItem (T("(Disconnected)"), 8);
modeSelector->addSeparator();
modeSelector->addItem (T("Named pipe (listening)"), 1);
modeSelector->addItem (T("Named pipe (connect to existing pipe)"), 5);
modeSelector->addSeparator();
modeSelector->addItem (T("Socket (listening)"), 2);
modeSelector->addItem (T("Socket (connect to existing socket)"), 6);
modeSelector->setSelectedId (8);
modeSelector->addListener (this);
addAndMakeVisible (pipeName = new TextEditor (T("pipe name:")));
pipeName->setBounds (100, 60, 130, 24);
pipeName->setMultiLine (false);
pipeName->setText (T("juce demo pipe"));
(new Label (pipeName->getName(), pipeName->getName()))->attachToComponent (pipeName, true);
addAndMakeVisible (socketNumber = new TextEditor (T("socket port:")));
socketNumber->setBounds (350, 60, 80, 24);
socketNumber->setMultiLine (false);
socketNumber->setText (T("12345"));
socketNumber->setInputRestrictions (5, T("0123456789"));
(new Label (socketNumber->getName(), socketNumber->getName()))->attachToComponent (socketNumber, true);
addAndMakeVisible (socketHost = new TextEditor (T("socket host:")));
socketHost->setBounds (530, 60, 130, 24);
socketHost->setMultiLine (false);
socketHost->setText (T("localhost"));
socketNumber->setInputRestrictions (512);
(new Label (socketHost->getName(), socketHost->getName()))->attachToComponent (socketHost, true);
addChildComponent (sendText = new TextEditor (T("sendtext")));
sendText->setBounds (30, 120, 200, 24);
sendText->setMultiLine (false);
sendText->setReadOnly (false);
sendText->setText (T("testing 1234"));
addChildComponent (sendButton = new TextButton (T("send"), T("Fires off the message")));
sendButton->setBounds (240, 120, 200, 24);
sendButton->changeWidthToFitText();
sendButton->addButtonListener (this);
addChildComponent (incomingMessages = new TextEditor (T("messages")));
incomingMessages->setReadOnly (true);
incomingMessages->setMultiLine (true);
incomingMessages->setBounds (30, 150, 500, 250);
// call this to set up everything's state correctly.
comboBoxChanged (0);
}
~InterprocessCommsDemo()
{
close();
delete server;
deleteAllChildren();
}
void buttonClicked (Button* button)
{
if (button == sendButton)
{
// The send button has been pressed, so write out the contents of the
// text box to the socket or pipe, depending on which is active.
const String text (sendText->getText());
MemoryBlock messageData ((const char*) text, text.length());
for (int i = activeConnections.size(); --i >= 0;)
{
if (! activeConnections[i]->sendMessage (messageData))
{
// the write failed, so indicate that the connection has broken..
appendMessage (T("send message failed!"));
}
}
}
}
void comboBoxChanged (ComboBox*)
{
// This is called when the user picks a different mode from the drop-down list..
const int modeId = modeSelector->getSelectedId();
close();
if (modeId < 8)
{
open ((modeId & 2) != 0,
(modeId & 4) != 0);
}
}
//==============================================================================
// Just closes any connections that are currently open.
void close()
{
server->stop();
activeConnections.clear();
// Reset the UI stuff to a disabled state.
sendText->setVisible (false);
sendButton->setVisible (false);
incomingMessages->setText (String::empty, false);
incomingMessages->setVisible (true);
appendMessage (
"To demonstrate named pipes, you'll need to run two instances of the JuceDemo application on this machine. On "
"one of them, select \"named pipe (listening)\", and then on the other, select \"named pipe (connect to existing pipe)\". Then messages that you "
"send from the 'sender' app should appear on the listener app. The \"pipe name\" field lets you choose a name for the pipe\n\n"
"To demonstrate sockets, you can either run two instances of the app on the same machine, or on different "
"machines on your network. In each one enter a socket number, then on one of the apps, select the "
"\"Socket (listening)\" mode. On the other, enter the host address of the listening app, and select \"Socket (connect to existing socket)\". "
"Messages should then be be sent between the apps in the same way as through the named pipes.");
}
void open (bool asSocket, bool asSender)
{
close();
// Make the appropriate bits of UI visible..
sendText->setVisible (true);
sendButton->setVisible (true);
incomingMessages->setText (String::empty, false);
incomingMessages->setVisible (true);
// and try to open the socket or pipe...
bool openedOk = false;
if (asSender)
{
// if we're connecting to an existing server, we can just create a connection object
// directly.
DemoInterprocessConnection* newConnection = new DemoInterprocessConnection (*this);
if (asSocket)
{
openedOk = newConnection->connectToSocket (socketHost->getText(),
socketNumber->getText().getIntValue(),
1000);
}
else
{
openedOk = newConnection->connectToPipe (pipeName->getText());
}
if (openedOk)
activeConnections.add (newConnection);
else
delete newConnection;
}
else
{
// if we're starting up a server, we need to tell the server to start waiting for
// clients to connect. It'll then create connection objects for us when clients arrive.
if (asSocket)
{
openedOk = server->beginWaitingForSocket (socketNumber->getText().getIntValue());
if (openedOk)
appendMessage (T("Waiting for another app to connect to this socket.."));
}
else
{
DemoInterprocessConnection* newConnection = new DemoInterprocessConnection (*this);
openedOk = newConnection->createPipe (pipeName->getText());
if (openedOk)
{
appendMessage (T("Waiting for another app to connect to this pipe.."));
activeConnections.add (newConnection);
}
else
{
delete newConnection;
}
}
}
if (! openedOk)
{
modeSelector->setSelectedId (8);
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Interprocess Comms Demo"),
T("Failed to open the socket or pipe..."));
}
}
void appendMessage (const String& message)
{
incomingMessages->setCaretPosition (INT_MAX);
incomingMessages->insertTextAtCursor (message + T("\n"));
incomingMessages->setCaretPosition (INT_MAX);
}
//==============================================================================
class DemoInterprocessConnection : public InterprocessConnection
{
InterprocessCommsDemo& owner;
int ourNumber;
public:
DemoInterprocessConnection (InterprocessCommsDemo& owner_)
: InterprocessConnection (true),
owner (owner_)
{
static int totalConnections = 0;
ourNumber = ++totalConnections;
}
~DemoInterprocessConnection()
{
}
void connectionMade()
{
owner.appendMessage (T("Connection #") + String (ourNumber) + T(" - connection started"));
}
void connectionLost()
{
owner.appendMessage (T("Connection #") + String (ourNumber) + T(" - connection lost"));
}
void messageReceived (const MemoryBlock& message)
{
owner.appendMessage (T("Connection #") + String (ourNumber) + T(" - message received: ") + message.toString());
}
};
//==============================================================================
class DemoInterprocessConnectionServer : public InterprocessConnectionServer
{
InterprocessCommsDemo& owner;
public:
DemoInterprocessConnectionServer (InterprocessCommsDemo& owner_)
: owner (owner_)
{
}
~DemoInterprocessConnectionServer()
{
}
InterprocessConnection* createConnectionObject()
{
DemoInterprocessConnection* newConnection = new DemoInterprocessConnection (owner);
owner.activeConnections.add (newConnection);
return newConnection;
}
};
OwnedArray <DemoInterprocessConnection, CriticalSection> activeConnections;
//==============================================================================
juce_UseDebuggingNewOperator
private:
ComboBox* modeSelector;
TextEditor* sendText;
TextButton* sendButton;
TextEditor* incomingMessages;
TextEditor* pipeName;
TextEditor* socketNumber;
TextEditor* socketHost;
DemoInterprocessConnectionServer* server;
};
//==============================================================================
Component* createInterprocessCommsDemo()
{
return new InterprocessCommsDemo();
}

View file

@ -1,269 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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.
==============================================================================
*/
#ifdef _WIN32
#include <windows.h>
#endif
#include "../jucedemo_headers.h"
#if JUCE_OPENGL
#ifdef _WIN32
#include <gl/gl.h>
#include <gl/glu.h>
#elif defined (LINUX)
#include <GL/gl.h>
#include <GL/glut.h>
#undef KeyPress
#else
#include <GLUT/glut.h>
#endif
#ifndef GL_BGRA_EXT
#define GL_BGRA_EXT 0x80e1
#endif
//==============================================================================
class DemoOpenGLCanvas : public OpenGLComponent,
public Timer
{
float rotation, delta;
Image* image;
public:
DemoOpenGLCanvas()
{
rotation = 0.0f;
delta = 1.0f;
Image* im = ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize);
image = new Image (Image::RGB, 512, 512, true);
Graphics g (*image);
g.fillAll (Colours::white);
g.drawImage (im, 0, 0, 512, 512, 0, 0, im->getWidth(), im->getHeight());
delete im;
startTimer (20);
// Just for demo purposes, let's dump a list of all the available pixel formats..
OwnedArray <OpenGLPixelFormat> availablePixelFormats;
OpenGLPixelFormat::getAvailablePixelFormats (this, availablePixelFormats);
for (int i = 0; i < availablePixelFormats.size(); ++i)
{
const OpenGLPixelFormat* const pixFormat = availablePixelFormats[i];
String formatDescription;
formatDescription
<< i << ": RGBA=(" << pixFormat->redBits
<< ", " << pixFormat->greenBits
<< ", " << pixFormat->blueBits
<< ", " << pixFormat->alphaBits
<< "), depth=" << pixFormat->depthBufferBits
<< ", stencil=" << pixFormat->stencilBufferBits
<< ", accum RGBA=(" << pixFormat->accumulationBufferRedBits
<< ", " << pixFormat->accumulationBufferGreenBits
<< ", " << pixFormat->accumulationBufferBlueBits
<< ", " << pixFormat->accumulationBufferAlphaBits
<< "), full-scene AA="
<< pixFormat->fullSceneAntiAliasingNumSamples;
Logger::outputDebugString (formatDescription);
}
}
~DemoOpenGLCanvas()
{
delete image;
}
// when the component creates a new internal context, this is called, and
// we'll use the opportunity to create the textures needed.
void newOpenGLContextCreated()
{
// (no need to call makeCurrentContextActive(), as that will have
// been done for us before the method call).
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth (1.0);
glDepthFunc (GL_LESS);
glEnable (GL_DEPTH_TEST);
glEnable (GL_TEXTURE_2D);
glEnable (GL_BLEND);
glShadeModel (GL_SMOOTH);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
int stride, pixStride;
const void* pixels = image->lockPixelDataReadOnly (0, 0, image->getWidth(), image->getHeight(), stride, pixStride);
glTexImage2D (GL_TEXTURE_2D, 0, 4, image->getWidth(), image->getHeight(),
0, GL_RGB,
GL_UNSIGNED_BYTE, pixels);
image->releasePixelDataReadOnly (pixels);
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void mouseDrag (const MouseEvent& e)
{
delta = e.getDistanceFromDragStartX() / 100.0f;
repaint();
}
void renderOpenGL()
{
glClearColor (0.8f, 0.0f, 0.4f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho (0.0, getWidth(), 0.0, getHeight(), 0, 1);
glColor4f (1.0f, 1.0f, 1.0f, fabsf (::sinf (rotation / 100.0f)));
glBegin(GL_QUADS);
glTexCoord2i (0, 0); glVertex2f (50.0f, getHeight() - 50.0f);
glTexCoord2i (1, 0); glVertex2f (getWidth() - 50.0f, getHeight() - 50.0f);
glTexCoord2i (1, 1); glVertex2f (getWidth() - 50.0f, 50.0f);
glTexCoord2i (0, 1); glVertex2f (50.0f, 50.0f);
glEnd();
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glClear (GL_DEPTH_BUFFER_BIT);
gluPerspective (45.0f,
getWidth() / (GLfloat) getHeight(),
0.1f,
100.0f);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef (0.0f, 0.0f, -5.0f);
glRotatef (rotation, 0.5f, 1.0f, 0.0f);
glBegin (GL_QUADS);
glColor3f (0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glColor3f (1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glColor3f (0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glColor3f (1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f (0.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glColor3f (1.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
}
void timerCallback()
{
rotation += delta;
repaint();
}
};
//==============================================================================
class OpenGLDemo : public Component
{
//==============================================================================
DemoOpenGLCanvas* canvas;
public:
//==============================================================================
OpenGLDemo()
{
setName (T("OpenGL"));
canvas = new DemoOpenGLCanvas();
addAndMakeVisible (canvas);
}
~OpenGLDemo()
{
deleteAllChildren();
}
void resized()
{
canvas->setBounds (10, 10, getWidth() - 20, getHeight() - 50);
}
};
//==============================================================================
Component* createOpenGLDemo()
{
return new OpenGLDemo();
}
#endif

View file

@ -1,378 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
static float randomNumber()
{
return Random::getSystemRandom().nextFloat() * 300.0f - 150.0f;
}
//==============================================================================
class PathsAndTransformsDemo : public Component,
public SliderListener,
public ComboBoxListener
{
public:
//==============================================================================
PathsAndTransformsDemo()
{
setName (T("Paths"));
// No parts of this component are semi-transparent, so calling setOpaque()
// allows the redraw system to exploit this fact and optimise repainting.
setOpaque (true);
generateRandomShape();
generateImage();
generateDrawable();
generateSVGDrawable();
addAndMakeVisible (typeChooser = new ComboBox (T("type")));
addAndMakeVisible (scaleSlider = new Slider (T("scale")));
addAndMakeVisible (angleSlider = new Slider (T("angle")));
addAndMakeVisible (xSlider = new Slider (T("x")));
addAndMakeVisible (ySlider = new Slider (T("y")));
addAndMakeVisible (opacitySlider = new Slider (T("opacity")));
(new Label (String::empty, T("type:"))) ->attachToComponent (typeChooser, true);
(new Label (String::empty, T("scale:"))) ->attachToComponent (scaleSlider, true);
(new Label (String::empty, T("angle:"))) ->attachToComponent (angleSlider, true);
(new Label (String::empty, T("x offset:"))) ->attachToComponent (xSlider, true);
(new Label (String::empty, T("y offset:"))) ->attachToComponent (ySlider, true);
(new Label (String::empty, T("opacity:"))) ->attachToComponent (opacitySlider, true);
typeChooser->addItem (T("random shape - solid colour"), 1);
typeChooser->addItem (T("random shape - linear gradient fill"), 2);
typeChooser->addItem (T("random shape - radial gradient fill"), 3);
typeChooser->addItem (T("random shape - tiled image fill"), 8);
typeChooser->addItem (T("image - low quality"), 4);
typeChooser->addItem (T("image - high quality"), 5);
typeChooser->addItem (T("image - colour-filled alpha channel"), 6);
typeChooser->addItem (T("image - gradient-filled alpha channel"), 7);
typeChooser->addItem (T("image - alphamap-filled alpha channel"), 9);
typeChooser->addItem (T("drawable object"), 10);
typeChooser->addItem (T("SVG object"), 11);
typeChooser->setSelectedId (11);
typeChooser->addListener (this);
scaleSlider ->addListener (this);
angleSlider ->addListener (this);
xSlider ->addListener (this);
ySlider ->addListener (this);
opacitySlider ->addListener (this);
scaleSlider->setRange (0.01, 10.0, 0.001);
scaleSlider->setValue (1.0);
angleSlider->setRange (-1.0, 1.0, 0.001);
angleSlider->setValue (0);
xSlider->setRange (-10, 10, 0.001);
xSlider->setValue (0);
ySlider->setRange (-10, 10, 0.001);
ySlider->setValue (0);
opacitySlider->setRange (0, 1, 0.01);
opacitySlider->setValue (1.0);
}
~PathsAndTransformsDemo()
{
if (image != 0)
delete image;
delete drawable;
delete svgDrawable;
deleteAllChildren();
}
void paint (Graphics& g)
{
g.fillCheckerBoard (0, 0, getWidth(), getHeight(),
50, 50,
Colour (0xffe0e0e0),
Colours::white);
const int type = typeChooser->getSelectedId();
if (type == 1)
{
g.setColour (Colours::blue.withAlpha ((float) opacitySlider->getValue()));
g.fillPath (shape, getTransform());
}
else if (type == 2 || type == 3)
{
GradientBrush gb (Colours::blue.withAlpha ((float) opacitySlider->getValue()),
getWidth() * 0.5f, getHeight() * 0.5f,
Colours::red.withAlpha ((float) opacitySlider->getValue()),
getWidth() * 0.6f, getHeight() * 0.7f,
type == 3);
g.setBrush (&gb);
g.fillPath (shape, getTransform());
}
else if (type == 8)
{
ImageBrush ib (image, 100, 100, (float) opacitySlider->getValue());
g.setBrush (&ib);
g.fillPath (shape, getTransform());
}
else if (type == 4 || type == 5)
{
if (type == 4)
g.setImageResamplingQuality (Graphics::lowResamplingQuality);
else
g.setImageResamplingQuality (Graphics::mediumResamplingQuality);
g.setOpacity ((float) opacitySlider->getValue());
if (image != 0)
{
g.drawImageTransformed (image,
0, 0, image->getWidth(), image->getHeight(),
AffineTransform::translation (-0.5f * image->getWidth(), -0.5f * image->getHeight())
.followedBy (getTransform()),
false);
}
}
else if (type == 6)
{
g.setColour (Colours::blue.withAlpha ((float) opacitySlider->getValue()));
if (image != 0)
{
g.drawImageTransformed (image,
0, 0, image->getWidth(), image->getHeight(),
AffineTransform::translation (-0.5f * image->getWidth(), -0.5f * image->getHeight())
.followedBy (getTransform()),
true);
}
}
else if (type == 7)
{
GradientBrush gb (Colours::blue.withAlpha ((float) opacitySlider->getValue()),
getWidth() * 0.5f, getHeight() * 0.5f,
Colours::red.withAlpha ((float) opacitySlider->getValue()),
getWidth() * 0.6f, getHeight() * 0.7f,
false);
g.setBrush (&gb);
if (image != 0)
{
g.drawImageTransformed (image,
0, 0, image->getWidth(), image->getHeight(),
AffineTransform::translation (-0.5f * image->getWidth(), -0.5f * image->getHeight())
.followedBy (getTransform()),
true);
}
}
else if (type == 9)
{
ImageBrush ib (image, 100, 100, (float) opacitySlider->getValue());
g.setBrush (&ib);
if (image != 0)
{
g.drawImageTransformed (image,
0, 0, image->getWidth(), image->getHeight(),
AffineTransform::translation (-0.5f * image->getWidth(),
-0.5f * image->getHeight())
.followedBy (getTransform()),
true);
}
}
else if (type == 10)
{
g.setOpacity ((float) opacitySlider->getValue());
float x, y, w, h;
drawable->getBounds (x, y, w, h);
drawable->draw (g, AffineTransform::translation (-x - 0.5f * w,
-y - 0.5f * h)
.followedBy (getTransform()));
}
else if (type == 11)
{
g.setOpacity ((float) opacitySlider->getValue());
float x, y, w, h;
svgDrawable->getBounds (x, y, w, h);
svgDrawable->draw (g, AffineTransform::translation (-x - 0.5f * w,
-y - 0.5f * h)
.followedBy (getTransform()));
}
}
void resized()
{
const int x = 100;
int y = 4;
typeChooser->setBounds (x, y, 300, 24);
y += 28;
scaleSlider->setBounds (x, y, 300, 24);
y += 28;
angleSlider->setBounds (x, y, 300, 24);
y += 28;
xSlider->setBounds (x, y, 300, 24);
y += 28;
ySlider->setBounds (x, y, 300, 24);
y += 28;
opacitySlider->setBounds (x, y, 300, 24);
}
void sliderValueChanged (Slider*)
{
repaint();
}
void comboBoxChanged (ComboBox*)
{
repaint();
}
private:
Path shape;
Image* image;
Drawable* drawable;
DrawableComposite* svgDrawable;
ComboBox* typeChooser;
Slider* scaleSlider;
Slider* angleSlider;
Slider* xSlider;
Slider* ySlider;
Slider* opacitySlider;
void generateRandomShape()
{
shape.startNewSubPath (randomNumber(), randomNumber());
for (int i = 0; i < 7; ++i)
{
shape.lineTo (randomNumber(), randomNumber());
shape.quadraticTo (randomNumber(), randomNumber(),
randomNumber(), randomNumber());
}
shape.closeSubPath();
}
void generateImage()
{
image = ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize);
}
void generateDrawable()
{
// create a composite drawable object..
DrawableComposite* dc = new DrawableComposite();
drawable = dc;
// ..add a paths drawable to it...
DrawablePath dp;
dp.setPath (shape);
dp.setOutline (4.0f, Colours::blue);
GradientBrush gb (ColourGradient (Colours::red.withAlpha (0.4f), -100.0f, -100.0f,
Colours::green.withAlpha (0.6f), 100.0f, 100.0f, false));
dp.setFillBrush (gb);
dc->insertDrawable (dp);
// ..add an image drawable..
DrawableImage di;
di.setImage (image, false);
dc->insertDrawable (di, AffineTransform::scale (0.3f, 0.8f));
// ..and a text object
DrawableText dt;
dt.setText (T("JUCE Drawables"), Font (30.0f, Font::bold));
dt.setColour (Colours::green);
dc->insertDrawable (dt, AffineTransform::translation (-80.0f, -20.0f)
.scaled (2.0f, 0.8f)
.rotated (-1.3f));
}
void generateSVGDrawable()
{
svgDrawable = 0;
MemoryInputStream iconsFileStream (BinaryData::icons_zip, BinaryData::icons_zipSize, false);
ZipFile icons (&iconsFileStream, false);
// Load a random SVG file from our embedded icons.zip file.
InputStream* svgFileStream
= icons.createStreamForEntry (Random::getSystemRandom().nextInt (icons.getNumEntries()));
if (svgFileStream != 0)
{
Drawable* loadedSVG = Drawable::createFromImageDataStream (*svgFileStream);
if (loadedSVG != 0)
{
// to make our icon the right size, we'll put it inside a DrawableComposite, and apply
// a transform to get it to the size we want.
float x, y, w, h;
loadedSVG->getBounds (x, y, w, h);
const float scaleFactor = 300.0f / jmax (w, h);
svgDrawable = new DrawableComposite();
svgDrawable->insertDrawable (loadedSVG, AffineTransform::scale (scaleFactor, scaleFactor));
}
delete svgFileStream;
}
}
const AffineTransform getTransform() const
{
return AffineTransform::rotation (float_Pi * 2.0f * (float) angleSlider->getValue())
.scaled ((float) scaleSlider->getValue(),
(float) scaleSlider->getValue())
.translated (getWidth() * 0.5f + (float) xSlider->getValue(),
getHeight() * 0.5f + (float) ySlider->getValue());
}
};
Component* createPathsAndTransformsDemo()
{
return new PathsAndTransformsDemo();
}

View file

@ -1,123 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
#if JUCE_QUICKTIME && ! JUCE_LINUX
//==============================================================================
// so that we can easily have two QT windows each with a file browser, wrap this up as a class..
class QuickTimeWindowWithFileBrowser : public Component,
public FilenameComponentListener
{
public:
QuickTimeWindowWithFileBrowser()
{
addAndMakeVisible (qtComp = new QuickTimeMovieComponent());
// and a file-chooser..
addAndMakeVisible (fileChooser = new FilenameComponent (T("movie"),
File::nonexistent,
true, false, false,
T("*.*"),
String::empty,
T("(choose a video file to play)")));
fileChooser->addListener (this);
fileChooser->setBrowseButtonText (T("browse"));
}
~QuickTimeWindowWithFileBrowser()
{
deleteAllChildren();
}
void resized()
{
qtComp->setBounds (0, 0, getWidth(), getHeight() - 30);
fileChooser->setBounds (0, getHeight() - 24, getWidth(), 24);
}
void filenameComponentChanged (FilenameComponent*)
{
// this is called when the user changes the filename in the file chooser box
if (qtComp->loadMovie (fileChooser->getCurrentFile(), true))
{
// loaded the file ok, so let's start it playing..
qtComp->play();
}
else
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Couldn't load the file!"),
T("Sorry, QuickTime didn't manage to load that file!"));
}
}
private:
QuickTimeMovieComponent* qtComp;
FilenameComponent* fileChooser;
};
//==============================================================================
class QuickTimeDemo : public Component
{
public:
//==============================================================================
QuickTimeDemo()
{
setName (T("QuickTime"));
// add a movie component..
addAndMakeVisible (qtComp1 = new QuickTimeWindowWithFileBrowser());
addAndMakeVisible (qtComp2 = new QuickTimeWindowWithFileBrowser());
}
~QuickTimeDemo()
{
deleteAllChildren();
}
void resized()
{
qtComp1->setBoundsRelative (0.05f, 0.05f, 0.425f, 0.9f);
qtComp2->setBoundsRelative (0.525f, 0.05f, 0.425f, 0.9f);
}
private:
//==============================================================================
QuickTimeWindowWithFileBrowser* qtComp1;
QuickTimeWindowWithFileBrowser* qtComp2;
};
//==============================================================================
Component* createQuickTimeDemo()
{
return new QuickTimeDemo();
}
#endif

View file

@ -1,325 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
/**
This class shows how to implement a TableListBoxModel to show in a TableListBox.
*/
class TableDemoComponent : public Component,
public TableListBoxModel
{
public:
//==============================================================================
TableDemoComponent()
: font (14.0f),
demoData (0)
{
// Load some data from an embedded XML file..
loadData();
// Create our table component and add it to this component..
addAndMakeVisible (table = new TableListBox (T("demo table"), this));
// give it a border
table->setColour (ListBox::outlineColourId, Colours::grey);
table->setOutlineThickness (1);
// Add some columns to the table header, based on the column list in our database..
forEachXmlChildElement (*columnList, columnXml)
{
table->getHeader()->addColumn (columnXml->getStringAttribute T("name"),
columnXml->getIntAttribute T("columnId"),
columnXml->getIntAttribute T("width"),
50, 400,
TableHeaderComponent::defaultFlags);
}
// we could now change some initial settings..
table->getHeader()->setSortColumnId (1, true); // sort forwards by the ID column
table->getHeader()->setColumnVisible (7, false); // hide the "length" column until the user shows it
// un-comment this line to have a go of stretch-to-fit mode
// table->getHeader()->setStretchToFitActive (true);
table->setMultipleSelectionEnabled (true);
}
~TableDemoComponent()
{
deleteAllChildren();
delete demoData;
}
//==============================================================================
// This is overloaded from TableListBoxModel, and must return the total number of rows in our table
int getNumRows()
{
return numRows;
}
// This is overloaded from TableListBoxModel, and should fill in the background of the whole row
void paintRowBackground (Graphics& g, int rowNumber, int width, int height, bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (Colours::lightblue);
}
// This is overloaded from TableListBoxModel, and must paint any cells that aren't using custom
// components.
void paintCell (Graphics& g,
int rowNumber,
int columnId,
int width, int height,
bool rowIsSelected)
{
g.setColour (Colours::black);
g.setFont (font);
const XmlElement* rowElement = dataList->getChildElement (rowNumber);
if (rowElement != 0)
{
const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
g.drawText (text, 2, 0, width - 4, height, Justification::centredLeft, true);
}
g.setColour (Colours::black.withAlpha (0.2f));
g.fillRect (width - 1, 0, 1, height);
}
// This is overloaded from TableListBoxModel, and tells us that the user has clicked a table header
// to change the sort order.
void sortOrderChanged (int newSortColumnId, const bool isForwards)
{
if (newSortColumnId != 0)
{
DemoDataSorter sorter (getAttributeNameForColumnId (newSortColumnId), isForwards);
dataList->sortChildElements (sorter);
table->updateContent();
}
}
// This is overloaded from TableListBoxModel, and must update any custom components that we're using
Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected,
Component* existingComponentToUpdate)
{
if (columnId == 5) // If it's the ratings column, we'll return our custom component..
{
RatingColumnCustomComponent* ratingsBox = (RatingColumnCustomComponent*) existingComponentToUpdate;
// If an existing component is being passed-in for updating, we'll re-use it, but
// if not, we'll have to create one.
if (ratingsBox == 0)
ratingsBox = new RatingColumnCustomComponent (*this);
ratingsBox->setRowAndColumn (rowNumber, columnId);
return ratingsBox;
}
else
{
// for any other column, just return 0, as we'll be painting these columns directly.
jassert (existingComponentToUpdate == 0);
return 0;
}
}
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
// column.
int getColumnAutoSizeWidth (int columnId)
{
if (columnId == 5)
return 100; // (this is the ratings column, containing a custom component)
int widest = 32;
// find the widest bit of text in this column..
for (int i = getNumRows(); --i >= 0;)
{
const XmlElement* rowElement = dataList->getChildElement (i);
if (rowElement != 0)
{
const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
widest = jmax (widest, font.getStringWidth (text));
}
}
return widest + 8;
}
// A couple of quick methods to set and get the "rating" value when the user
// changes the combo box
int getRating (const int rowNumber, const int columnId) const
{
return dataList->getChildElement (rowNumber)->getIntAttribute (T("Rating"));
}
void setRating (const int rowNumber, const int columnId, const int newRating)
{
dataList->getChildElement (rowNumber)->setAttribute (T("Rating"), newRating);
}
//==============================================================================
void resized()
{
// position our table with a gap around its edge
table->setBoundsInset (BorderSize (8));
}
//==============================================================================
juce_UseDebuggingNewOperator
private:
TableListBox* table; // the table component itself
Font font;
XmlElement* demoData; // This is the XML document loaded from the embedded file "demo table data.xml"
XmlElement* columnList; // A pointer to the sub-node of demoData that contains the list of columns
XmlElement* dataList; // A pointer to the sub-node of demoData that contains the list of data rows
int numRows; // The number of rows of data we've got
//==============================================================================
// This is a custom component containing a combo box, which we're going to put inside
// our table's "rating" column.
class RatingColumnCustomComponent : public Component,
public ComboBoxListener
{
public:
RatingColumnCustomComponent (TableDemoComponent& owner_)
: owner (owner_)
{
// just put a combo box inside this component
addAndMakeVisible (comboBox = new ComboBox (String::empty));
comboBox->addItem (T("fab"), 1);
comboBox->addItem (T("groovy"), 2);
comboBox->addItem (T("hep"), 3);
comboBox->addItem (T("neat"), 4);
comboBox->addItem (T("wild"), 5);
comboBox->addItem (T("swingin"), 6);
comboBox->addItem (T("mad for it"), 7);
// when the combo is changed, we'll get a callback.
comboBox->addListener (this);
comboBox->setWantsKeyboardFocus (false);
}
~RatingColumnCustomComponent()
{
deleteAllChildren();
}
void resized()
{
comboBox->setBoundsInset (BorderSize (2));
}
// Our demo code will call this when we may need to update our contents
void setRowAndColumn (const int newRow, const int newColumn)
{
row = newRow;
columnId = newColumn;
comboBox->setSelectedId (owner.getRating (row, columnId), true);
}
void comboBoxChanged (ComboBox* comboBoxThatHasChanged)
{
owner.setRating (row, columnId, comboBox->getSelectedId());
}
private:
TableDemoComponent& owner;
ComboBox* comboBox;
int row, columnId;
};
//==============================================================================
// A comparator used to sort our data when the user clicks a column header
class DemoDataSorter
{
public:
DemoDataSorter (const String attributeToSort_, bool forwards)
: attributeToSort (attributeToSort_),
direction (forwards ? 1 : -1)
{
}
int compareElements (XmlElement* first, XmlElement* second) const
{
int result = first->getStringAttribute (attributeToSort)
.compareLexicographically (second->getStringAttribute (attributeToSort));
if (result == 0)
result = first->getStringAttribute (T("ID"))
.compareLexicographically (second->getStringAttribute (T("ID")));
return direction * result;
}
private:
const String attributeToSort;
const int direction;
};
//==============================================================================
// this loads the embedded database XML file into memory
void loadData()
{
XmlDocument dataDoc (String ((const char*) BinaryData::demo_table_data_xml));
demoData = dataDoc.getDocumentElement();
dataList = demoData->getChildByName (T("DATA"));
columnList = demoData->getChildByName (T("COLUMNS"));
numRows = dataList->getNumChildElements();
}
// (a utility method to search our XML for the attribute that matches a column ID)
const String getAttributeNameForColumnId (const int columnId) const
{
forEachXmlChildElement (*columnList, columnXml)
{
if (columnXml->getIntAttribute T("columnId") == columnId)
return columnXml->getStringAttribute T("name");
}
return String::empty;
}
};
//==============================================================================
Component* createTableDemo()
{
return new TableDemoComponent();
}

View file

@ -1,351 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
class BouncingBallComp : public Component
{
float x, y, size, dx, dy, w, h, parentWidth, parentHeight;
float innerX, innerY;
Colour colour;
Thread::ThreadID threadId;
public:
BouncingBallComp()
{
x = Random::getSystemRandom().nextFloat() * 200.0f;
y = Random::getSystemRandom().nextFloat() * 200.0f;
parentWidth = 50;
parentHeight = 50;
innerX = 0;
innerY = 0;
threadId = 0;
const float speed = 5.0f; // give each ball a fixed speed so we can
// see the effects of thread priority on how fast
// they actually go.
const float angle = Random::getSystemRandom().nextFloat() * float_Pi * 2.0f;
dx = sinf (angle) * speed;
dy = cosf (angle) * speed;
size = Random::getSystemRandom().nextFloat() * 30.0f + 30.0f;
colour = Colour (Random::getSystemRandom().nextInt())
.withAlpha (0.5f)
.withBrightness (0.7f);
}
~BouncingBallComp()
{
}
void paint (Graphics& g)
{
g.setColour (colour);
g.fillEllipse (innerX, innerY, size, size);
g.setColour (Colours::black);
g.setFont (10.0f);
g.drawText (String::toHexString ((int64) threadId), 0, 0, getWidth(), getHeight(), Justification::centred, false);
}
void parentSizeChanged()
{
parentWidth = getParentWidth() - size;
parentHeight = getParentHeight() - size;
}
void moveBall()
{
threadId = Thread::getCurrentThreadId(); // this is so the component can print the thread ID inside the ball
x += dx;
y += dy;
if (x < 0)
dx = fabsf (dx);
if (x > parentWidth)
dx = -fabsf (dx);
if (y < 0)
dy = fabsf (dy);
if (y > parentHeight)
dy = -fabsf (dy);
setBounds (((int) x) - 2,
((int) y) - 2,
((int) size) + 4,
((int) size) + 4);
innerX = x - getX();
innerY = y - getY();
repaint();
}
juce_UseDebuggingNewOperator
};
//==============================================================================
class DemoThread : public BouncingBallComp,
public Thread
{
int interval;
public:
DemoThread()
: Thread (T("Juce Demo Thread"))
{
interval = Random::getSystemRandom().nextInt (50) + 6;
// give the threads a random priority, so some will move more
// smoothly than others..
startThread (Random::getSystemRandom().nextInt (3) + 3);
}
~DemoThread()
{
// allow the thread 2 seconds to stop cleanly - should be plenty of time.
stopThread (2000);
}
void run()
{
// this is the code that runs this thread - we'll loop continuously,
// updating the co-ordinates of our blob.
// threadShouldExit() returns true when the stopThread() method has been
// called, so we should check it often, and exit as soon as it gets flagged.
while (! threadShouldExit())
{
// sleep a bit so the threads don't all grind the CPU to a halt..
wait (interval);
// because this is a background thread, we mustn't do any UI work without
// first grabbing a MessageManagerLock..
const MessageManagerLock mml (Thread::getCurrentThread());
if (! mml.lockWasGained()) // if something is trying to kill this job, the lock
return; // will fail, in which case we'd better return..
// now we've got the UI thread locked, we can mess about with the components
moveBall();
}
}
juce_UseDebuggingNewOperator
};
//==============================================================================
class DemoThreadPoolJob : public BouncingBallComp,
public ThreadPoolJob
{
public:
DemoThreadPoolJob()
: ThreadPoolJob (T("Demo Threadpool Job"))
{
}
~DemoThreadPoolJob()
{
}
JobStatus runJob()
{
// this is the code that runs this job. It'll be repeatedly called until we return
// jobHasFinished instead of jobNeedsRunningAgain.
Thread::sleep (30);
// because this is a background thread, we mustn't do any UI work without
// first grabbing a MessageManagerLock..
const MessageManagerLock mml (this);
// before moving the ball, we need to check whether the lock was actually gained, because
// if something is trying to stop this job, it will have failed..
if (mml.lockWasGained())
moveBall();
return jobNeedsRunningAgain;
}
void removedFromQueue()
{
// This is called to tell us that our job has been removed from the pool.
// In this case there's no need to do anything here.
}
juce_UseDebuggingNewOperator
};
//==============================================================================
class ThreadingDemo : public Component,
public Timer,
public ButtonListener
{
bool isUsingPool;
ThreadPool pool;
TextButton* controlButton;
public:
//==============================================================================
ThreadingDemo()
: pool (3)
{
isUsingPool = false;
setName (T("Multithreading"));
setOpaque (true);
}
~ThreadingDemo()
{
pool.removeAllJobs (true, 2000);
deleteAllChildren();
}
// this gets called when a component is added or removed from a parent component.
void parentHierarchyChanged()
{
// we'll use this as an opportunity to start and stop the threads, so that
// we don't leave them going when the component's not actually visible.
stopTimer();
pool.removeAllJobs (true, 4000);
deleteAllChildren();
addAndMakeVisible (controlButton = new TextButton (T("Thread type")));
controlButton->changeWidthToFitText (20);
controlButton->setTopLeftPosition (20, 20);
controlButton->setTriggeredOnMouseDown (true);
controlButton->setAlwaysOnTop (true);
controlButton->addButtonListener (this);
if (isShowing())
{
while (getNumChildComponents() < 5)
addABall();
startTimer (2000);
}
}
void paint (Graphics& g)
{
g.fillAll (Colours::white);
}
void setUsingPool (bool usePool)
{
isUsingPool = usePool;
parentHierarchyChanged(); // resets everything
}
void addABall()
{
if (isUsingPool)
{
DemoThreadPoolJob* newComp = new DemoThreadPoolJob();
addAndMakeVisible (newComp);
newComp->parentSizeChanged();
pool.addJob (newComp);
}
else
{
DemoThread* newComp = new DemoThread();
addAndMakeVisible (newComp);
newComp->parentSizeChanged();
}
}
void removeABall()
{
if (isUsingPool)
{
ThreadPoolJob* jobToRemove = pool.getJob (Random::getSystemRandom().nextInt (pool.getNumJobs()));
if (jobToRemove != 0)
{
pool.removeJob (jobToRemove, true, 4000);
delete jobToRemove;
}
}
else
{
if (getNumChildComponents() > 1)
{
Component* ball = getChildComponent (1 + Random::getSystemRandom().nextInt (getNumChildComponents() - 1));
if (dynamic_cast <Button*> (ball) == 0) // don't delete our button!
delete ball;
}
}
}
void timerCallback()
{
if (Random::getSystemRandom().nextBool())
{
if (getNumChildComponents() <= 10)
addABall();
}
else
{
if (getNumChildComponents() > 3)
removeABall();
}
}
void buttonClicked (Button* button)
{
PopupMenu m;
m.addItem (1, T("Use one thread per ball"), true, ! isUsingPool);
m.addItem (2, T("Use a thread pool"), true, isUsingPool);
const int res = m.showAt (button);
if (res != 0)
setUsingPool (res == 2);
}
};
//==============================================================================
Component* createThreadingDemo()
{
return new ThreadingDemo();
}

View file

@ -1,271 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
class TreeViewDemoItem : public TreeViewItem
{
XmlElement* xml;
public:
TreeViewDemoItem (XmlElement* const xml_)
: xml (xml_)
{
}
~TreeViewDemoItem()
{
}
int getItemWidth() const
{
return xml->getIntAttribute (T("width"), -1);
}
const String getUniqueName() const
{
if (xml != 0)
return xml->getTagName();
else
return String::empty;
}
bool mightContainSubItems()
{
return xml != 0
&& xml->getFirstChildElement() != 0;
}
void paintItem (Graphics& g, int width, int height)
{
if (xml != 0)
{
// if this item is selected, fill it with a background colour..
if (isSelected())
g.fillAll (Colours::blue.withAlpha (0.3f));
// use a "colour" attribute in the xml tag for this node to set the text colour..
g.setColour (Colour (xml->getStringAttribute (T("colour"), T("ff000000")).getHexValue32()));
g.setFont (height * 0.7f);
// draw the xml element's tag name..
g.drawText (xml->getTagName(),
4, 0, width - 4, height,
Justification::centredLeft, true);
}
}
void itemOpennessChanged (bool isNowOpen)
{
if (isNowOpen)
{
// if we've not already done so, we'll now add the tree's sub-items. You could
// also choose to delete the existing ones and refresh them if that's more suitable
// in your app.
if (getNumSubItems() == 0)
{
// create and add sub-items to this node of the tree, corresponding to
// each sub-element in the XML..
if (xml != 0)
{
forEachXmlChildElement (*xml, child)
{
addSubItem (new TreeViewDemoItem (child));
}
}
}
}
else
{
// in this case, we'll leave any sub-items in the tree when the node gets closed,
// though you could choose to delete them if that's more appropriate for
// your application.
}
}
const String getDragSourceDescription()
{
return T("TreeView Items");
}
};
//==============================================================================
class TreeViewDemo : public Component,
public DragAndDropContainer,
public ButtonListener
{
XmlElement* treeXml;
TreeViewItem* rootItem;
TreeView* treeView;
FileTreeComponent* fileTreeComp;
DirectoryContentsList* directoryList;
TimeSliceThread thread;
TextButton* typeButton;
public:
//==============================================================================
TreeViewDemo()
: treeView (0),
rootItem (0),
fileTreeComp (0),
directoryList (0),
thread ("Demo file tree thread")
{
setName (T("Tree Views"));
const String treeXmlString (BinaryData::treedemo_xml);
XmlDocument parser (treeXmlString);
treeXml = parser.getDocumentElement();
rootItem = new TreeViewDemoItem (treeXml);
rootItem->setOpen (true);
// find the root of the user's home drive, and set that as our root..
File folder (File::getSpecialLocation (File::userHomeDirectory));
while (folder.getParentDirectory() != folder)
folder = folder.getParentDirectory();
directoryList = new DirectoryContentsList (0, thread);
directoryList->setDirectory (folder, true, true);
thread.startThread (3);
addAndMakeVisible (typeButton = new TextButton (T("Type of treeview...")));
typeButton->addButtonListener (this);
typeButton->setAlwaysOnTop (true);
typeButton->setTriggeredOnMouseDown (true);
showCustomTreeView();
}
~TreeViewDemo()
{
deleteAllChildren();
delete rootItem;
delete treeXml;
delete directoryList;
}
void paint (Graphics& g)
{
g.setColour (Colours::grey);
if (treeView != 0)
g.drawRect (treeView->getX(), treeView->getY(),
treeView->getWidth(), treeView->getHeight());
if (fileTreeComp != 0)
g.drawRect (fileTreeComp->getX(), fileTreeComp->getY(),
fileTreeComp->getWidth(), fileTreeComp->getHeight());
}
void resized()
{
if (treeView != 0)
treeView->setBoundsInset (BorderSize (40, 10, 10, 10));
else if (fileTreeComp != 0)
fileTreeComp->setBoundsInset (BorderSize (40, 10, 10, 10));
typeButton->changeWidthToFitText (22);
typeButton->setTopLeftPosition (10, 10);
}
void showCustomTreeView()
{
deleteAndZero (treeView);
deleteAndZero (fileTreeComp);
addAndMakeVisible (treeView = new TreeView());
treeView->setRootItem (rootItem);
treeView->setMultiSelectEnabled (true);
resized();
}
void showFileTreeComp()
{
deleteAndZero (treeView);
deleteAndZero (fileTreeComp);
addAndMakeVisible (fileTreeComp = new FileTreeComponent (*directoryList));
resized();
}
void buttonClicked (Button*)
{
PopupMenu m;
m.addItem (1, T("Custom treeview showing an XML tree"));
m.addItem (2, T("FileTreeComponent showing the file system"));
m.addSeparator();
m.addItem (3, T("Show root item"), true,
treeView != 0 ? treeView->isRootItemVisible()
: fileTreeComp->isRootItemVisible());
m.addItem (4, T("Show open/close buttons"), true,
treeView != 0 ? treeView->areOpenCloseButtonsVisible()
: fileTreeComp->areOpenCloseButtonsVisible());
const int r = m.showAt (typeButton);
if (r == 1)
{
showCustomTreeView();
}
else if (r == 2)
{
showFileTreeComp();
}
else if (r == 3)
{
if (treeView != 0)
treeView->setRootItemVisible (! treeView->isRootItemVisible());
else
fileTreeComp->setRootItemVisible (! fileTreeComp->isRootItemVisible());
}
else if (r == 4)
{
if (treeView != 0)
treeView->setOpenCloseButtonsVisible (! treeView->areOpenCloseButtonsVisible());
else
fileTreeComp->setOpenCloseButtonsVisible (! fileTreeComp->areOpenCloseButtonsVisible());
}
}
juce_UseDebuggingNewOperator
};
//==============================================================================
Component* createTreeViewDemo()
{
return new TreeViewDemo();
}

View file

@ -1,148 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
#if JUCE_WEB_BROWSER
//==============================================================================
/** We'll use a subclass of WebBrowserComponent to demonstrate how to get callbacks
when the browser changes URL. You don't need to do this, you can just also
just use the WebBrowserComponent class directly.
*/
class DemoBrowserComponent : public WebBrowserComponent
{
public:
//==============================================================================
DemoBrowserComponent (TextEditor* addressTextBox_)
: addressTextBox (addressTextBox_)
{
}
// This method gets called when the browser is about to go to a new URL..
bool pageAboutToLoad (const String& newURL)
{
// We'll just update our address box to reflect the new location..
addressTextBox->setText (newURL, false);
// we could return false here to tell the browser not to go ahead with
// loading the page.
return true;
}
//==============================================================================
juce_UseDebuggingNewOperator
private:
TextEditor* addressTextBox;
DemoBrowserComponent (DemoBrowserComponent&);
const DemoBrowserComponent& operator= (const DemoBrowserComponent&);
};
//==============================================================================
class WebBrowserDemo : public Component,
public TextEditorListener,
public ButtonListener
{
public:
//==============================================================================
WebBrowserDemo()
{
setName ("Web Browser");
// Create an address box..
addAndMakeVisible (addressTextBox = new TextEditor());
addressTextBox->setTextToShowWhenEmpty ("Enter a web address, e.g. http://www.rawmaterialsoftware.com", Colours::grey);
addressTextBox->addListener (this);
// create the actual browser component
addAndMakeVisible (webView = new DemoBrowserComponent (addressTextBox));
// add some buttons..
addAndMakeVisible (goButton = new TextButton ("Go", "Go to URL"));
goButton->addButtonListener (this);
addAndMakeVisible (backButton = new TextButton ("<<", "Back"));
backButton->addButtonListener (this);
addAndMakeVisible (forwardButton = new TextButton (">>", "Forward"));
forwardButton->addButtonListener (this);
// send the browser to a start page..
webView->goToURL ("http://www.google.com");
}
~WebBrowserDemo()
{
deleteAllChildren();
}
void resized()
{
webView->setBounds (10, 45, getWidth() - 20, getHeight() - 55);
goButton->setBounds (getWidth() - 45, 10, 35, 25);
addressTextBox->setBounds (100, 10, getWidth() - 155, 25);
backButton->setBounds (10, 10, 35, 25);
forwardButton->setBounds (55, 10, 35, 25);
}
void textEditorTextChanged (TextEditor& editor) {}
void textEditorEscapeKeyPressed (TextEditor& editor) {}
void textEditorFocusLost (TextEditor& editor) {}
void textEditorReturnKeyPressed (TextEditor&)
{
webView->goToURL (addressTextBox->getText());
}
void buttonClicked (Button* b)
{
if (b == backButton)
webView->goBack();
else if (b == forwardButton)
webView->goForward();
else if (b == goButton)
webView->goToURL (addressTextBox->getText());
}
juce_UseDebuggingNewOperator
private:
DemoBrowserComponent* webView;
TextEditor* addressTextBox;
TextButton* goButton;
TextButton* backButton;
TextButton* forwardButton;
};
//==============================================================================
Component* createWebBrowserDemo()
{
return new WebBrowserDemo();
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,637 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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 "../jucedemo_headers.h"
//==============================================================================
/** Our demo synth only has one type of sound, and it's very basic..
*/
class SineWaveSound : public SynthesiserSound
{
public:
SineWaveSound (const BitArray& midiNotes_)
: midiNotes (midiNotes_)
{
}
bool appliesToNote (const int midiNoteNumber)
{
return midiNotes [midiNoteNumber];
}
bool appliesToChannel (const int midiChannel) { return true; }
private:
// this will contain the notes that this sound is attached to.
BitArray midiNotes;
};
//==============================================================================
/** Our demo synth voice just plays a sine wave..
*/
class SineWaveVoice : public SynthesiserVoice
{
public:
SineWaveVoice()
: angleDelta (0.0),
tailOff (0.0)
{
}
bool canPlaySound (SynthesiserSound* sound)
{
return dynamic_cast <SineWaveSound*> (sound) != 0;
}
void startNote (const int midiNoteNumber, const float velocity,
SynthesiserSound* sound, const int currentPitchWheelPosition)
{
currentAngle = 0.0;
level = velocity * 0.15;
tailOff = 0.0;
double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
double cyclesPerSample = cyclesPerSecond / getSampleRate();
angleDelta = cyclesPerSample * 2.0 * double_Pi;
}
void stopNote (const bool allowTailOff)
{
if (allowTailOff)
{
// start a tail-off by setting this flag. The render callback will pick up on
// this and do a fade out, calling clearCurrentNote() when it's finished.
if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
// stopNote method could be called more than once.
tailOff = 1.0;
}
else
{
// we're being told to stop playing immediately, so reset everything..
clearCurrentNote();
angleDelta = 0.0;
}
}
void pitchWheelMoved (const int newValue)
{
// can't be bothered implementing this for the demo!
}
void controllerMoved (const int controllerNumber, const int newValue)
{
// not interested in controllers in this case.
}
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (angleDelta != 0.0)
{
if (tailOff > 0)
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level * tailOff);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
tailOff *= 0.99;
if (tailOff <= 0.005)
{
clearCurrentNote();
angleDelta = 0.0;
break;
}
}
}
else
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
}
}
}
}
private:
double currentAngle, angleDelta, level, tailOff;
};
//==============================================================================
/** This is an audio source that streams the output of our demo synth.
*/
class SynthAudioSource : public AudioSource
{
public:
//==============================================================================
// this collects real-time midi messages from the midi input device, and
// turns them into blocks that we can process in our audio callback
MidiMessageCollector midiCollector;
// this represents the state of which keys on our on-screen keyboard are held
// down. When the mouse is clicked on the keyboard component, this object also
// generates midi messages for this, which we can pass on to our synth.
MidiKeyboardState keyboardState;
// the synth itself!
Synthesiser synth;
//==============================================================================
SynthAudioSource()
{
// we'll be mixing two different types of sound, so here we'll create two
// sets of note maps, putting each sound on a different octave of the keyboard:
BitArray sinewaveNotes, samplerNotes;
int i;
for (i = 0; i < 128; ++i)
{
if (((i / 12) & 1) != 0)
sinewaveNotes.setBit (i);
else
samplerNotes.setBit (i);
}
// add a wave sound, which will get applied to some of the notes..
synth.addSound (new SineWaveSound (sinewaveNotes));
// give our synth a few voices that can play the wave sound..
for (i = 4; --i >= 0;)
synth.addVoice (new SineWaveVoice());
WavAudioFormat wavFormat;
AudioFormatReader* audioReader
= wavFormat.createReaderFor (new MemoryInputStream (BinaryData::cello_wav,
BinaryData::cello_wavSize,
false),
true);
synth.addSound (new SamplerSound (T("demo sound"),
*audioReader,
samplerNotes,
74, // root midi note
0.1, // attack time
0.1, // release time
10.0 // maximum sample length
));
delete audioReader;
// and give the synth some sampler voices to play the sampled sound..
for (i = 4; --i >= 0;)
synth.addVoice (new SamplerVoice());
}
void prepareToPlay (int samplesPerBlockExpected,
double sampleRate)
{
midiCollector.reset (sampleRate);
synth.setCurrentPlaybackSampleRate (sampleRate);
}
void releaseResources()
{
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
// the synth always adds its output to the audio buffer, so we have to clear it
// first..
bufferToFill.clearActiveBufferRegion();
// fill a midi buffer with incoming messages from the midi input.
MidiBuffer incomingMidi;
midiCollector.removeNextBlockOfMessages (incomingMidi, bufferToFill.numSamples);
// pass these messages to the keyboard state so that it can update the component
// to show on-screen which keys are being pressed on the physical midi keyboard.
// This call will also add midi messages to the buffer which were generated by
// the mouse-clicking on the on-screen keyboard.
keyboardState.processNextMidiBuffer (incomingMidi, 0, bufferToFill.numSamples, true);
// and now get the synth to process the midi events and generate its output.
synth.renderNextBlock (*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}
};
//==============================================================================
class AudioInputWaveformDisplay : public Component,
public Timer,
public AudioIODeviceCallback
{
public:
AudioInputWaveformDisplay()
{
bufferPos = 0;
bufferSize = 2048;
circularBuffer = (float*) juce_calloc (sizeof (float) * bufferSize);
currentInputLevel = 0.0f;
numSamplesIn = 0;
setOpaque (true);
startTimer (1000 / 50); // repaint every 1/50 of a second
}
~AudioInputWaveformDisplay()
{
juce_free (circularBuffer);
}
void paint (Graphics& g)
{
g.fillAll (Colours::black);
g.setColour (Colours::lightgreen);
const float halfHeight = getHeight() * 0.5f;
int bp = bufferPos;
for (int x = getWidth(); --x >= 0;)
{
const int samplesAgo = getWidth() - x;
const float level = circularBuffer [(bp + bufferSize - samplesAgo) % bufferSize];
if (level > 0.01f)
g.drawLine ((float) x, halfHeight - halfHeight * level,
(float) x, halfHeight + halfHeight * level);
}
}
void timerCallback()
{
repaint();
}
void addSample (const float sample)
{
currentInputLevel += fabsf (sample);
const int samplesToAverage = 128;
if (++numSamplesIn > samplesToAverage)
{
circularBuffer [bufferPos++ % bufferSize] = currentInputLevel / samplesToAverage;
numSamplesIn = 0;
currentInputLevel = 0.0f;
}
}
void audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
for (int i = 0; i < totalNumInputChannels; ++i)
{
if (inputChannelData [i] != 0)
{
for (int j = 0; j < numSamples; ++j)
addSample (inputChannelData [i][j]);
break;
}
}
}
void audioDeviceAboutToStart (AudioIODevice*)
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
void audioDeviceStopped()
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
private:
float* circularBuffer;
float currentInputLevel;
int volatile bufferPos, bufferSize, numSamplesIn;
};
//==============================================================================
class AudioDemo : public Component,
public FilenameComponentListener,
public ButtonListener,
public ChangeListener,
public AudioIODeviceCallback
{
//==============================================================================
FilenameComponent* fileChooser;
TextButton* playButton;
TextButton* stopButton;
TextButton* audioSettingsButton;
MidiKeyboardComponent* keyboardComponent;
AudioInputWaveformDisplay* waveformComponent;
//==============================================================================
// this wraps the actual audio device
AudioDeviceManager audioDeviceManager;
// this allows an audio source to be streamed to the IO device
AudioSourcePlayer audioSourcePlayer;
// this controls the playback of a positionable audio stream, handling the
// starting/stopping and sample-rate conversion
AudioTransportSource transportSource;
// this source contains our synth, and generates its output
SynthAudioSource synthSource;
// this source is used to mix together the output from our synth source
// and wave player source
MixerAudioSource mixerSource;
// this is the actual stream that's going to read from the audio file.
AudioFormatReaderSource* currentAudioFileSource;
File currentFile;
public:
//==============================================================================
AudioDemo()
{
setName (T("Audio"));
currentAudioFileSource = 0;
//==============================================================================
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
addAndMakeVisible (fileChooser = new FilenameComponent (T("audiofile"),
File::nonexistent,
true, false, false,
formatManager.getWildcardForAllFormats(),
String::empty,
T("(choose a WAV or AIFF file to play)")));
fileChooser->addListener (this);
fileChooser->setBrowseButtonText (T("browse"));
addAndMakeVisible (playButton = new TextButton (T("play"),
T("click here to play the current audio file")));
playButton->addButtonListener (this);
playButton->setColour (TextButton::buttonColourId, Colours::lightgreen);
playButton->setColour (TextButton::buttonOnColourId, Colours::lightgreen);
playButton->setConnectedEdges (Button::ConnectedOnRight);
addAndMakeVisible (stopButton = new TextButton (T("stop"),
T("click here to play the current audio file")));
stopButton->addButtonListener (this);
stopButton->setColour (TextButton::buttonColourId, Colours::red);
stopButton->setColour (TextButton::buttonOnColourId, Colours::red);
stopButton->setConnectedEdges (Button::ConnectedOnLeft);
addAndMakeVisible (audioSettingsButton = new TextButton (T("show audio settings..."),
T("click here to change the audio device settings")));
audioSettingsButton->addButtonListener (this);
addAndMakeVisible (keyboardComponent = new MidiKeyboardComponent (synthSource.keyboardState,
MidiKeyboardComponent::horizontalKeyboard));
addAndMakeVisible (waveformComponent = new AudioInputWaveformDisplay());
//==============================================================================
// register for start/stop messages from the transport source..
transportSource.addChangeListener (this);
// and initialise the device manager with no settings so that it picks a
// default device to use.
const String error (audioDeviceManager.initialise (1, /* number of input channels */
2, /* number of output channels */
0, /* no XML settings.. */
true /* select default device on failure */));
if (error.isNotEmpty())
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Audio Demo"),
T("Couldn't open an output device!\n\n") + error);
}
else
{
// add the two audio sources to our mixer..
mixerSource.addInputSource (&transportSource, false);
mixerSource.addInputSource (&synthSource, false);
// ..and connect the mixer to our source player.
audioSourcePlayer.setSource (&mixerSource);
// start the IO device pulling its data from our callback..
audioDeviceManager.addAudioCallback (this);
// and we need to send midi input to our synth for processing
audioDeviceManager.addMidiInputCallback (String::empty, &synthSource.midiCollector);
}
}
~AudioDemo()
{
audioDeviceManager.removeMidiInputCallback (String::empty, &synthSource.midiCollector);
audioDeviceManager.removeAudioCallback (this);
transportSource.removeChangeListener (this);
transportSource.setSource (0);
deleteAndZero (currentAudioFileSource);
audioSourcePlayer.setSource (0);
deleteAllChildren();
}
//==============================================================================
void audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
// pass the audio callback on to our player source, and also the waveform display comp
audioSourcePlayer.audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
}
void audioDeviceAboutToStart (AudioIODevice* device)
{
audioSourcePlayer.audioDeviceAboutToStart (device);
waveformComponent->audioDeviceAboutToStart (device);
}
void audioDeviceStopped()
{
audioSourcePlayer.audioDeviceStopped();
waveformComponent->audioDeviceStopped();
}
//==============================================================================
void paint (Graphics& g)
{
// print some text to explain what state we're in.
g.setColour (Colours::black);
g.setFont (14.0f);
String s;
if (transportSource.isPlaying())
s = T("playing");
else
s = T("stopped");
if (currentAudioFileSource == 0)
s += T(" - no source file selected");
else
s += T(" - file: \"") + currentFile.getFullPathName() + T("\"");
g.drawText (s, 250, 50, getWidth() - 250, 24, Justification::centredLeft, true);
}
void resized()
{
fileChooser->setBounds (10, 10, getWidth() - 20, 24);
playButton->setBounds (10, 50, 100, 24);
stopButton->setBounds (110, 50, 100, 24);
audioSettingsButton->setBounds (10, 120, 200, 24);
audioSettingsButton->changeWidthToFitText();
keyboardComponent->setBounds (10, 200, getWidth() - 20, 60);
waveformComponent->setBounds (10, 300, 400, 80);
updateButtons();
}
void updateButtons()
{
playButton->setEnabled (currentAudioFileSource != 0 && ! transportSource.isPlaying());
stopButton->setEnabled (transportSource.isPlaying());
repaint();
}
void buttonClicked (Button* button)
{
if (button == playButton)
{
transportSource.setPosition (0.0);
transportSource.start();
}
else if (button == stopButton)
{
transportSource.stop();
}
else if (button == audioSettingsButton)
{
// Create an AudioDeviceSelectorComponent which contains the audio choice widgets...
AudioDeviceSelectorComponent audioSettingsComp (audioDeviceManager,
0, 1,
2, 2,
true,
false,
true,
false);
// ...and show it in a DialogWindow...
audioSettingsComp.setSize (500, 450);
DialogWindow::showModalDialog (T("Audio Settings"),
&audioSettingsComp,
this,
Colours::azure,
true);
}
}
void filenameComponentChanged (FilenameComponent*)
{
// this is called when the user changes the filename in the file chooser box
File audioFile (fileChooser->getCurrentFile());
// unload the previous file source and delete it..
transportSource.stop();
transportSource.setSource (0);
deleteAndZero (currentAudioFileSource);
// create a new file source from the file..
// get a format manager and set it up with the basic types (wav and aiff).
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
AudioFormatReader* reader = formatManager.createReaderFor (audioFile);
if (reader != 0)
{
currentFile = audioFile;
currentAudioFileSource = new AudioFormatReaderSource (reader, true);
// ..and plug it into our transport source
transportSource.setSource (currentAudioFileSource,
32768, // tells it to buffer this many samples ahead
reader->sampleRate);
}
updateButtons();
}
void changeListenerCallback (void*)
{
// callback from the transport source to tell us that play has
// started or stopped, so update our buttons..
updateButtons();
}
};
//==============================================================================
Component* createAudioDemo()
{
return new AudioDemo();
}

View file

@ -0,0 +1,371 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 5:32:11 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoLatencyPage.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
//==============================================================================
class LatencyTester : public AudioIODeviceCallback,
public Timer
{
public:
LatencyTester (TextEditor* resultsBox_)
: testSound (1, 1),
recordedSound (1, 1),
playingSampleNum (0),
recordedSampleNum (-1),
sineWaveFrequency (300.0),
isRunning (false),
resultsBox (resultsBox_)
{
}
~LatencyTester()
{
}
//==============================================================================
void beginTest()
{
startTimer (50);
const ScopedLock sl (lock);
recordedSound.clear();
playingSampleNum = recordedSampleNum = 0;
isRunning = true;
}
void timerCallback()
{
if (isRunning && recordedSampleNum >= recordedSound.getNumSamples())
{
isRunning = false;
stopTimer();
// Test has finished, so calculate the result..
String message;
const int latencySamples = calculateLatencySamples();
if (latencySamples >= 0)
{
message << "\n\nLatency test results:\n"
<< latencySamples << " samples (" << (latencySamples * 1000.0 / sampleRate) << " milliseconds)\n"
<< "The audio device reports an input latency of "
<< deviceInputLatency << " samples, output latency of "
<< deviceOutputLatency << " samples."
<< "\nSo the corrected latency = "
<< (latencySamples - deviceInputLatency - deviceOutputLatency)
<< " samples (" << ((latencySamples - deviceInputLatency - deviceOutputLatency) * 1000.0 / sampleRate)
<< " milliseconds)";
}
else
{
message = "\n\nCouldn't detect the test signal!!\nMake sure there's no background noise that might be confusing it..";
}
resultsBox->setCaretPosition (INT_MAX);
resultsBox->insertTextAtCursor (message);
resultsBox->setCaretPosition (INT_MAX);
}
}
//==============================================================================
void audioDeviceAboutToStart (AudioIODevice* device)
{
isRunning = false;
sampleRate = device->getCurrentSampleRate();
deviceInputLatency = device->getInputLatencyInSamples();
deviceOutputLatency = device->getOutputLatencyInSamples();
playingSampleNum = recordedSampleNum = 0;
createTestSound();
recordedSound.setSize (1, (int) (1.5 * sampleRate));
recordedSound.clear();
}
void audioDeviceStopped()
{
}
void audioDeviceIOCallback (const float** inputChannelData,
int numInputChannels,
float** outputChannelData,
int numOutputChannels,
int numSamples)
{
const ScopedLock sl (lock);
if (isRunning)
{
float* const recordingBuffer = recordedSound.getSampleData (0, 0);
const float* const playBuffer = testSound.getSampleData (0, 0);
for (int i = 0; i < numSamples; ++i)
{
if (recordedSampleNum < recordedSound.getNumSamples())
{
float inputSamp = 0;
for (int j = numInputChannels; --j >= 0;)
if (inputChannelData[j] != 0)
inputSamp += inputChannelData[j][i];
recordingBuffer [recordedSampleNum] = inputSamp;
}
++recordedSampleNum;
float outputSamp = (playingSampleNum < testSound.getNumSamples()) ? playBuffer [playingSampleNum] : 0;
for (int j = numOutputChannels; --j >= 0;)
if (outputChannelData[j] != 0)
outputChannelData[j][i] = outputSamp;
++playingSampleNum;
}
}
else
{
// We need to clear the output buffers, in case they're full of junk..
for (int i = 0; i < numOutputChannels; ++i)
if (outputChannelData[i] != 0)
zeromem (outputChannelData[i], sizeof (float) * numSamples);
}
}
private:
AudioSampleBuffer testSound, recordedSound;
int playingSampleNum, recordedSampleNum;
CriticalSection lock;
const double sineWaveFrequency;
double sampleRate;
bool isRunning;
TextEditor* resultsBox;
int deviceInputLatency, deviceOutputLatency;
void createTestSound()
{
const int length = ((int) sampleRate) / 4;
testSound.setSize (1, length);
testSound.clear();
float* s = testSound.getSampleData (0, 0);
const double scale = 2.0 * double_Pi / (sampleRate / sineWaveFrequency);
int n = 0;
for (int i = 512; i < length; ++i)
s[i] = 0.95f * sinf ((float) (scale * n++));
testSound.applyGainRamp (0, length - length / 3, length / 3, 1.0f, 0.0f);
}
int findStartSampleOfSineWave (const AudioSampleBuffer& buffer, const double sampleRate) const
{
const float* s = buffer.getSampleData (0, 0);
const double damping = 0.995;
double avG = 0;
for (int i = 0; i < buffer.getNumSamples(); i += 2)
{
const int num = jmin (512, buffer.getNumSamples() - i);
const double g = calcGoertzel (s + i, num, sampleRate, sineWaveFrequency);
avG = avG * damping + (1.0 - damping) * g * g;
if (avG > 3)
return i;
}
return -1;
}
static double calcGoertzel (const float* const samples, const int numSamples,
const double sampleRate, const double frequency) throw()
{
double n = 0, n1 = 0;
const double pi2freqOverRate = (2.0 * double_Pi) * frequency / sampleRate;
const double multiplier = 2.0 * cos (pi2freqOverRate);
for (int i = 0; i < numSamples; ++i)
{
const double n2 = n1;
n1 = n;
n = multiplier * n1 - n2 + samples[i];
}
return n - n1 * exp (-pi2freqOverRate);
}
int calculateLatencySamples() const
{
// Detect the sound in both our test sound and the recording of it, and measure the difference
// in their start times..
const int referenceStart = findStartSampleOfSineWave (testSound, sampleRate);
jassert (referenceStart >= 0);
const int recordedStart = findStartSampleOfSineWave (recordedSound, sampleRate);
return (recordedStart < 0) ? -1 : (recordedStart - referenceStart);
}
LatencyTester (const LatencyTester&);
const LatencyTester& operator= (const LatencyTester&);
};
//[/MiscUserDefs]
//==============================================================================
AudioDemoLatencyPage::AudioDemoLatencyPage (AudioDeviceManager& deviceManager_)
: deviceManager (deviceManager_),
liveAudioDisplayComp (0),
startTestButton (0),
testResultsBox (0)
{
addAndMakeVisible (liveAudioDisplayComp = new LiveAudioInputDisplayComp());
addAndMakeVisible (startTestButton = new TextButton (String::empty));
startTestButton->setButtonText (T("Test Latency"));
startTestButton->addButtonListener (this);
addAndMakeVisible (testResultsBox = new TextEditor (String::empty));
testResultsBox->setMultiLine (true);
testResultsBox->setReturnKeyStartsNewLine (true);
testResultsBox->setReadOnly (true);
testResultsBox->setScrollbarsShown (true);
testResultsBox->setCaretVisible (false);
testResultsBox->setPopupMenuEnabled (true);
testResultsBox->setColour (TextEditor::backgroundColourId, Colour (0x32ffffff));
testResultsBox->setColour (TextEditor::outlineColourId, Colour (0x1c000000));
testResultsBox->setColour (TextEditor::shadowColourId, Colour (0x16000000));
testResultsBox->setText (T("Running this test measures the round-trip latency between the audio output and input devices you\'ve got selected.\n\nIt\'ll play a sound, then try to measure the time at which the sound arrives back at the audio input. Obviously for this to work you need to have your microphone somewhere near your speakers..."));
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
deviceManager.addAudioCallback (liveAudioDisplayComp);
latencyTester = new LatencyTester (testResultsBox);
deviceManager.addAudioCallback (latencyTester);
//[/Constructor]
}
AudioDemoLatencyPage::~AudioDemoLatencyPage()
{
//[Destructor_pre]. You can add your own custom destruction code here..
deviceManager.removeAudioCallback (liveAudioDisplayComp);
deviceManager.removeAudioCallback (latencyTester);
delete latencyTester;
//[/Destructor_pre]
deleteAndZero (liveAudioDisplayComp);
deleteAndZero (startTestButton);
deleteAndZero (testResultsBox);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoLatencyPage::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::lightgrey);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoLatencyPage::resized()
{
liveAudioDisplayComp->setBounds (8, 8, getWidth() - 16, 64);
startTestButton->setBounds (8, getHeight() - 41, 168, 32);
testResultsBox->setBounds (8, 88, getWidth() - 16, getHeight() - 137);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
void AudioDemoLatencyPage::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == startTestButton)
{
//[UserButtonCode_startTestButton] -- add your button handler code here..
latencyTester->beginTest();
//[/UserButtonCode_startTestButton]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoLatencyPage" componentName=""
parentClasses="public Component" constructorParams="AudioDeviceManager&amp; deviceManager_"
variableInitialisers="deviceManager (deviceManager_)" snapPixels="8"
snapActive="1" snapShown="1" overlayOpacity="0.330000013" fixedSize="0"
initialWidth="600" initialHeight="400">
<BACKGROUND backgroundColour="ffd3d3d3"/>
<GENERICCOMPONENT name="" id="7d70eb2617f56220" memberName="liveAudioDisplayComp"
virtualName="" explicitFocusOrder="0" pos="8 8 16M 64" class="LiveAudioInputDisplayComp"
params=""/>
<TEXTBUTTON name="" id="83ed8fcbf36419df" memberName="startTestButton" virtualName=""
explicitFocusOrder="0" pos="8 41R 168 32" buttonText="Test Latency"
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
<TEXTEDITOR name="" id="95d03a8403bc35da" memberName="testResultsBox" virtualName=""
explicitFocusOrder="0" pos="8 88 16M 137M" bkgcol="32ffffff"
outlinecol="1c000000" shadowcol="16000000" initialText="Running this test measures the round-trip latency between the audio output and input devices you've got selected.&#10;&#10;It'll play a sound, then try to measure the time at which the sound arrives back at the audio input. Obviously for this to work you need to have your microphone somewhere near your speakers..."
multiline="1" retKeyStartsLine="1" readonly="1" scrollbars="1"
caret="0" popupmenu="1"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,79 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 5:32:11 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMOLATENCYPAGE_AUDIODEMOLATENCYPAGE_BFCD772A__
#define __JUCER_HEADER_AUDIODEMOLATENCYPAGE_AUDIODEMOLATENCYPAGE_BFCD772A__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
#include "AudioDemoTabComponent.h"
class LatencyTester;
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Jucer.
Describe your class and how it works here!
//[/Comments]
*/
class AudioDemoLatencyPage : public Component,
public ButtonListener
{
public:
//==============================================================================
AudioDemoLatencyPage (AudioDeviceManager& deviceManager_);
~AudioDemoLatencyPage();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
//[/UserMethods]
void paint (Graphics& g);
void resized();
void buttonClicked (Button* buttonThatWasClicked);
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager;
LatencyTester* latencyTester;
//[/UserVariables]
//==============================================================================
LiveAudioInputDisplayComp* liveAudioDisplayComp;
TextButton* startTestButton;
TextEditor* testResultsBox;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoLatencyPage (const AudioDemoLatencyPage&);
const AudioDemoLatencyPage& operator= (const AudioDemoLatencyPage&);
};
#endif // __JUCER_HEADER_AUDIODEMOLATENCYPAGE_AUDIODEMOLATENCYPAGE_BFCD772A__

View file

@ -0,0 +1,352 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 7:17:11 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoPlaybackPage.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
class DemoThumbnailComp : public Component,
public ChangeListener
{
public:
DemoThumbnailComp()
: thumbnailCache (5),
thumbnail (512, formatManager, thumbnailCache)
{
startTime = endTime = 0;
formatManager.registerBasicFormats();
thumbnail.addChangeListener (this);
}
~DemoThumbnailComp()
{
thumbnail.removeChangeListener (this);
}
void setFile (const File& file)
{
thumbnail.setSource (new FileInputSource (file));
startTime = 0;
endTime = thumbnail.getTotalLength();
}
void setZoomFactor (double amount)
{
if (thumbnail.getTotalLength() > 0)
{
double timeDisplayed = jmax (0.001, (thumbnail.getTotalLength() - startTime) * (1.0 - jlimit (0.0, 1.0, amount)));
endTime = startTime + timeDisplayed;
repaint();
}
}
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY)
{
if (thumbnail.getTotalLength() > 0)
{
double newStart = startTime + (wheelIncrementX + wheelIncrementY) * (endTime - startTime) / 10.0;
newStart = jlimit (0.0, thumbnail.getTotalLength() - (endTime - startTime), newStart);
endTime = newStart + (endTime - startTime);
startTime = newStart;
repaint();
}
}
void paint (Graphics& g)
{
g.fillAll (Colours::white);
g.setColour (Colours::mediumblue);
if (thumbnail.getTotalLength() > 0)
{
int heightPerChannel = (getHeight() - 4) / thumbnail.getNumChannels();
for (int i = 0; i < thumbnail.getNumChannels(); ++i)
{
thumbnail.drawChannel (g, 2, 2 + heightPerChannel * i,
getWidth() - 4, heightPerChannel,
startTime, endTime,
i, 1.0f);
}
}
else
{
g.setFont (14.0f);
g.drawFittedText ("(No audio file selected)", 0, 0, getWidth(), getHeight(), Justification::centred, 2);
}
}
void changeListenerCallback (void*)
{
// this method is called by the thumbnail when it has changed, so we should repaint it..
repaint();
}
AudioFormatManager formatManager;
AudioThumbnailCache thumbnailCache;
AudioThumbnail thumbnail;
double startTime, endTime;
};
//[/MiscUserDefs]
//==============================================================================
AudioDemoPlaybackPage::AudioDemoPlaybackPage (AudioDeviceManager& deviceManager_)
: deviceManager (deviceManager_),
thread ("audio file preview"),
directoryList (0, thread),
zoomLabel (0),
thumbnail (0),
startStopButton (0),
fileTreeComp (0),
explanation (0),
zoomSlider (0)
{
addAndMakeVisible (zoomLabel = new Label (String::empty,
T("zoom:")));
zoomLabel->setFont (Font (15.0000f, Font::plain));
zoomLabel->setJustificationType (Justification::centredRight);
zoomLabel->setEditable (false, false, false);
zoomLabel->setColour (TextEditor::textColourId, Colours::black);
zoomLabel->setColour (TextEditor::backgroundColourId, Colour (0x0));
addAndMakeVisible (thumbnail = new DemoThumbnailComp());
addAndMakeVisible (startStopButton = new TextButton (String::empty));
startStopButton->setButtonText (T("Play/Stop"));
startStopButton->addButtonListener (this);
startStopButton->setColour (TextButton::buttonColourId, Colour (0xff79ed7f));
addAndMakeVisible (fileTreeComp = new FileTreeComponent (directoryList));
addAndMakeVisible (explanation = new Label (String::empty,
T("Select an audio file in the treeview above, and this page will display its waveform, and let you play it..")));
explanation->setFont (Font (14.0000f, Font::plain));
explanation->setJustificationType (Justification::bottomRight);
explanation->setEditable (false, false, false);
explanation->setColour (TextEditor::textColourId, Colours::black);
explanation->setColour (TextEditor::backgroundColourId, Colour (0x0));
addAndMakeVisible (zoomSlider = new Slider (String::empty));
zoomSlider->setRange (0, 1, 0);
zoomSlider->setSliderStyle (Slider::LinearHorizontal);
zoomSlider->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
zoomSlider->addListener (this);
zoomSlider->setSkewFactor (2);
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
directoryList.setDirectory (File::getSpecialLocation (File::userHomeDirectory), true, true);
thread.startThread (3);
fileTreeComp->setColour (FileTreeComponent::backgroundColourId, Colours::white);
fileTreeComp->addListener (this);
deviceManager.addAudioCallback (&audioSourcePlayer);
audioSourcePlayer.setSource (&transportSource);
currentAudioFileSource = 0;
//[/Constructor]
}
AudioDemoPlaybackPage::~AudioDemoPlaybackPage()
{
//[Destructor_pre]. You can add your own custom destruction code here..
transportSource.setSource (0);
audioSourcePlayer.setSource (0);
deviceManager.removeAudioCallback (&audioSourcePlayer);
fileTreeComp->removeListener (this);
deleteAndZero (currentAudioFileSource);
//[/Destructor_pre]
deleteAndZero (zoomLabel);
deleteAndZero (thumbnail);
deleteAndZero (startStopButton);
deleteAndZero (fileTreeComp);
deleteAndZero (explanation);
deleteAndZero (zoomSlider);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoPlaybackPage::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::lightgrey);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoPlaybackPage::resized()
{
zoomLabel->setBounds (16, getHeight() - 90, 55, 24);
thumbnail->setBounds (16, getHeight() - 221, getWidth() - 32, 123);
startStopButton->setBounds (16, getHeight() - 46, 150, 32);
fileTreeComp->setBounds (16, 8, getWidth() - 32, getHeight() - 245);
explanation->setBounds (256, getHeight() - 82, getWidth() - 275, 64);
zoomSlider->setBounds (72, getHeight() - 90, 200, 24);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
void AudioDemoPlaybackPage::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == startStopButton)
{
//[UserButtonCode_startStopButton] -- add your button handler code here..
if (transportSource.isPlaying())
{
transportSource.stop();
}
else
{
transportSource.setPosition (0);
transportSource.start();
}
//[/UserButtonCode_startStopButton]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
void AudioDemoPlaybackPage::sliderValueChanged (Slider* sliderThatWasMoved)
{
//[UsersliderValueChanged_Pre]
//[/UsersliderValueChanged_Pre]
if (sliderThatWasMoved == zoomSlider)
{
//[UserSliderCode_zoomSlider] -- add your slider handling code here..
thumbnail->setZoomFactor (zoomSlider->getValue());
//[/UserSliderCode_zoomSlider]
}
//[UsersliderValueChanged_Post]
//[/UsersliderValueChanged_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void AudioDemoPlaybackPage::loadFileIntoTransport (const File& audioFile)
{
// unload the previous file source and delete it..
transportSource.stop();
transportSource.setSource (0);
deleteAndZero (currentAudioFileSource);
// get a format manager and set it up with the basic types (wav and aiff).
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
AudioFormatReader* reader = formatManager.createReaderFor (audioFile);
if (reader != 0)
{
currentAudioFileSource = new AudioFormatReaderSource (reader, true);
// ..and plug it into our transport source
transportSource.setSource (currentAudioFileSource,
32768, // tells it to buffer this many samples ahead
reader->sampleRate);
}
}
void AudioDemoPlaybackPage::selectionChanged()
{
loadFileIntoTransport (fileTreeComp->getSelectedFile());
zoomSlider->setValue (0, false, false);
thumbnail->setFile (fileTreeComp->getSelectedFile());
}
void AudioDemoPlaybackPage::fileClicked (const File& file, const MouseEvent& e)
{
}
void AudioDemoPlaybackPage::fileDoubleClicked (const File& file)
{
}
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoPlaybackPage" componentName=""
parentClasses="public Component, public FileBrowserListener"
constructorParams="AudioDeviceManager&amp; deviceManager_" variableInitialisers="deviceManager (deviceManager_),&#10;thread (&quot;audio file preview&quot;),&#10;directoryList (0, thread)"
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330000013"
fixedSize="0" initialWidth="600" initialHeight="400">
<BACKGROUND backgroundColour="ffd3d3d3"/>
<LABEL name="" id="d4f78f975d81c8d3" memberName="zoomLabel" virtualName=""
explicitFocusOrder="0" pos="16 90R 55 24" edTextCol="ff000000"
edBkgCol="0" labelText="zoom:" editableSingleClick="0" editableDoubleClick="0"
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
bold="0" italic="0" justification="34"/>
<GENERICCOMPONENT name="" id="beef657b0e007936" memberName="thumbnail" virtualName=""
explicitFocusOrder="0" pos="16 221R 32M 123" class="DemoThumbnailComp"
params=""/>
<TEXTBUTTON name="" id="abe446e2f3f09420" memberName="startStopButton" virtualName=""
explicitFocusOrder="0" pos="16 46R 150 32" bgColOff="ff79ed7f"
buttonText="Play/Stop" connectedEdges="0" needsCallback="1" radioGroupId="0"/>
<GENERICCOMPONENT name="" id="1de1dc6a18a9032b" memberName="fileTreeComp" virtualName=""
explicitFocusOrder="0" pos="16 8 32M 245M" class="FileTreeComponent"
params="directoryList"/>
<LABEL name="" id="7db7d0a64ef21311" memberName="explanation" virtualName=""
explicitFocusOrder="0" pos="256 82R 275M 64" edTextCol="ff000000"
edBkgCol="0" labelText="Select an audio file in the treeview above, and this page will display its waveform, and let you play it.."
editableSingleClick="0" editableDoubleClick="0" focusDiscardsChanges="0"
fontname="Default font" fontsize="14" bold="0" italic="0" justification="18"/>
<SLIDER name="" id="38bbc108f4c96092" memberName="zoomSlider" virtualName=""
explicitFocusOrder="0" pos="72 90R 200 24" min="0" max="1" int="0"
style="LinearHorizontal" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="2"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,96 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 7:17:11 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMOPLAYBACKPAGE_AUDIODEMOPLAYBACKPAGE_8AB55057__
#define __JUCER_HEADER_AUDIODEMOPLAYBACKPAGE_AUDIODEMOPLAYBACKPAGE_8AB55057__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
class DemoThumbnailComp;
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Jucer.
Describe your class and how it works here!
//[/Comments]
*/
class AudioDemoPlaybackPage : public Component,
public FileBrowserListener,
public ButtonListener,
public SliderListener
{
public:
//==============================================================================
AudioDemoPlaybackPage (AudioDeviceManager& deviceManager_);
~AudioDemoPlaybackPage();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
// These methods are our FileBrowserListener implementation:
void selectionChanged();
void fileClicked (const File& file, const MouseEvent& e);
void fileDoubleClicked (const File& file);
//[/UserMethods]
void paint (Graphics& g);
void resized();
void buttonClicked (Button* buttonThatWasClicked);
void sliderValueChanged (Slider* sliderThatWasMoved);
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager;
TimeSliceThread thread;
DirectoryContentsList directoryList;
AudioSourcePlayer audioSourcePlayer;
AudioTransportSource transportSource;
AudioFormatReaderSource* currentAudioFileSource;
void loadFileIntoTransport (const File& audioFile);
//[/UserVariables]
//==============================================================================
Label* zoomLabel;
DemoThumbnailComp* thumbnail;
TextButton* startStopButton;
FileTreeComponent* fileTreeComp;
Label* explanation;
Slider* zoomSlider;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoPlaybackPage (const AudioDemoPlaybackPage&);
const AudioDemoPlaybackPage& operator= (const AudioDemoPlaybackPage&);
};
#endif // __JUCER_HEADER_AUDIODEMOPLAYBACKPAGE_AUDIODEMOPLAYBACKPAGE_8AB55057__

View file

@ -0,0 +1,392 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 19 Sep 2009 12:36:23 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoRecordPage.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
//==============================================================================
/* This is a rough-and-ready circular buffer, used to allow the audio thread to
push data quickly into a queue, allowing a background thread to come along and
write it to disk later.
*/
class CircularAudioBuffer
{
public:
CircularAudioBuffer (const int numChannels, const int numSamples)
: buffer (numChannels, numSamples)
{
clear();
}
~CircularAudioBuffer()
{
}
void clear()
{
buffer.clear();
const ScopedLock sl (bufferLock);
bufferValidStart = bufferValidEnd = 0;
}
void addSamplesToBuffer (const AudioSampleBuffer& sourceBuffer, int numSamples)
{
const int bufferSize = buffer.getNumSamples();
bufferLock.enter();
int newDataStart = bufferValidEnd;
int newDataEnd = newDataStart + numSamples;
const int actualNewDataEnd = newDataEnd;
bufferValidStart = jmax (bufferValidStart, newDataEnd - bufferSize);
bufferLock.exit();
newDataStart %= bufferSize;
newDataEnd %= bufferSize;
if (newDataEnd < newDataStart)
{
for (int i = jmin (buffer.getNumChannels(), sourceBuffer.getNumChannels()); --i >= 0;)
{
buffer.copyFrom (i, newDataStart, sourceBuffer, i, 0, bufferSize - newDataStart);
buffer.copyFrom (i, 0, sourceBuffer, i, bufferSize - newDataStart, newDataEnd);
}
}
else
{
for (int i = jmin (buffer.getNumChannels(), sourceBuffer.getNumChannels()); --i >= 0;)
buffer.copyFrom (i, newDataStart, sourceBuffer, i, 0, newDataEnd - newDataStart);
}
const ScopedLock sl (bufferLock);
bufferValidEnd = actualNewDataEnd;
}
int readSamplesFromBuffer (AudioSampleBuffer& destBuffer, int numSamples)
{
const int bufferSize = buffer.getNumSamples();
bufferLock.enter();
int availableDataStart = bufferValidStart;
const int numSamplesDone = jmin (numSamples, bufferValidEnd - availableDataStart);
int availableDataEnd = availableDataStart + numSamplesDone;
bufferValidStart = availableDataEnd;
bufferLock.exit();
availableDataStart %= bufferSize;
availableDataEnd %= bufferSize;
if (availableDataEnd < availableDataStart)
{
for (int i = jmin (buffer.getNumChannels(), destBuffer.getNumChannels()); --i >= 0;)
{
destBuffer.copyFrom (i, 0, buffer, i, availableDataStart, bufferSize - availableDataStart);
destBuffer.copyFrom (i, bufferSize - availableDataStart, buffer, i, 0, availableDataEnd);
}
}
else
{
for (int i = jmin (buffer.getNumChannels(), destBuffer.getNumChannels()); --i >= 0;)
destBuffer.copyFrom (i, 0, buffer, i, availableDataStart, numSamplesDone);
}
return numSamplesDone;
}
private:
CriticalSection bufferLock;
AudioSampleBuffer buffer;
int bufferValidStart, bufferValidEnd;
};
//==============================================================================
class AudioRecorder : public AudioIODeviceCallback,
public Thread
{
public:
AudioRecorder()
: Thread ("audio recorder"),
circularBuffer (2, 48000),
recording (false),
sampleRate (0)
{
}
~AudioRecorder()
{
stop();
}
//==============================================================================
void startRecording (const File& file)
{
stop();
if (sampleRate > 0)
{
fileToRecord = file;
startThread();
circularBuffer.clear();
recording = true;
}
}
void stop()
{
recording = false;
stopThread (5000);
}
bool isRecording() const
{
return isThreadRunning() && recording;
}
//==============================================================================
void audioDeviceAboutToStart (AudioIODevice* device)
{
sampleRate = device->getCurrentSampleRate();
}
void audioDeviceStopped()
{
sampleRate = 0;
}
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels,
int numSamples)
{
if (recording)
{
const AudioSampleBuffer incomingData ((float**) inputChannelData, numInputChannels, numSamples);
circularBuffer.addSamplesToBuffer (incomingData, numSamples);
}
// We need to clear the output buffers, in case they're full of junk..
for (int i = 0; i < numOutputChannels; ++i)
if (outputChannelData[i] != 0)
zeromem (outputChannelData[i], sizeof (float) * numSamples);
}
//==============================================================================
void run()
{
fileToRecord.deleteFile();
OutputStream* outStream = fileToRecord.createOutputStream();
if (outStream == 0)
return;
WavAudioFormat wavFormat;
AudioFormatWriter* writer = wavFormat.createWriterFor (outStream, sampleRate, 1, 16, StringPairArray(), 0);
if (writer == 0)
{
delete outStream;
return;
}
AudioSampleBuffer tempBuffer (2, 8192);
while (! threadShouldExit())
{
int numSamplesReady = circularBuffer.readSamplesFromBuffer (tempBuffer, tempBuffer.getNumSamples());
if (numSamplesReady > 0)
tempBuffer.writeToAudioWriter (writer, 0, numSamplesReady);
Thread::sleep (1);
}
delete writer;
}
File fileToRecord;
double sampleRate;
bool recording;
CircularAudioBuffer circularBuffer;
};
//[/MiscUserDefs]
//==============================================================================
AudioDemoRecordPage::AudioDemoRecordPage (AudioDeviceManager& deviceManager_)
: deviceManager (deviceManager_),
liveAudioDisplayComp (0),
explanationLabel (0),
recordButton (0)
{
addAndMakeVisible (liveAudioDisplayComp = new LiveAudioInputDisplayComp());
addAndMakeVisible (explanationLabel = new Label (String::empty,
T("This page demonstrates how to record a wave file from the live audio input..\n\nPressing record will start recording a file to your desktop.")));
explanationLabel->setFont (Font (15.0000f, Font::plain));
explanationLabel->setJustificationType (Justification::topLeft);
explanationLabel->setEditable (false, false, false);
explanationLabel->setColour (TextEditor::textColourId, Colours::black);
explanationLabel->setColour (TextEditor::backgroundColourId, Colour (0x0));
addAndMakeVisible (recordButton = new TextButton (String::empty));
recordButton->setButtonText (T("Record"));
recordButton->addButtonListener (this);
recordButton->setColour (TextButton::buttonColourId, Colour (0xffff5c5c));
recordButton->setColour (TextButton::textColourId, Colours::black);
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
recorder = new AudioRecorder();
deviceManager.addAudioCallback (recorder);
deviceManager.addAudioCallback (liveAudioDisplayComp);
//[/Constructor]
}
AudioDemoRecordPage::~AudioDemoRecordPage()
{
//[Destructor_pre]. You can add your own custom destruction code here..
recorder->stop();
deviceManager.removeAudioCallback (recorder);
delete recorder;
deviceManager.removeAudioCallback (liveAudioDisplayComp);
//[/Destructor_pre]
deleteAndZero (liveAudioDisplayComp);
deleteAndZero (explanationLabel);
deleteAndZero (recordButton);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoRecordPage::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::lightgrey);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoRecordPage::resized()
{
liveAudioDisplayComp->setBounds (8, 8, getWidth() - 16, 64);
explanationLabel->setBounds (184, 88, getWidth() - 194, 120);
recordButton->setBounds (8, 88, 136, 40);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
void AudioDemoRecordPage::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == recordButton)
{
//[UserButtonCode_recordButton] -- add your button handler code here..
if (recorder->isRecording())
{
recorder->stop();
}
else
{
File file (File::getSpecialLocation (File::userDesktopDirectory)
.getNonexistentChildFile ("Juce Demo Audio Recording", ".wav"));
recorder->startRecording (file);
}
if (recorder->isRecording())
recordButton->setButtonText ("Stop");
else
recordButton->setButtonText ("Record");
//[/UserButtonCode_recordButton]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
void AudioDemoRecordPage::visibilityChanged()
{
//[UserCode_visibilityChanged] -- Add your code here...
recorder->stop();
recordButton->setButtonText ("Record");
//[/UserCode_visibilityChanged]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoRecordPage" componentName=""
parentClasses="public Component" constructorParams="AudioDeviceManager&amp; deviceManager_"
variableInitialisers="deviceManager (deviceManager_)" snapPixels="8"
snapActive="1" snapShown="1" overlayOpacity="0.330000013" fixedSize="0"
initialWidth="600" initialHeight="400">
<METHODS>
<METHOD name="visibilityChanged()"/>
</METHODS>
<BACKGROUND backgroundColour="ffd3d3d3"/>
<GENERICCOMPONENT name="" id="7d70eb2617f56220" memberName="liveAudioDisplayComp"
virtualName="" explicitFocusOrder="0" pos="8 8 16M 64" class="LiveAudioInputDisplayComp"
params=""/>
<LABEL name="" id="1162fb2599a768b4" memberName="explanationLabel" virtualName=""
explicitFocusOrder="0" pos="184 88 194M 120" edTextCol="ff000000"
edBkgCol="0" labelText="This page demonstrates how to record a wave file from the live audio input..&#10;&#10;Pressing record will start recording a file to your desktop."
editableSingleClick="0" editableDoubleClick="0" focusDiscardsChanges="0"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="9"/>
<TEXTBUTTON name="" id="2c10a0ba9fad39da" memberName="recordButton" virtualName=""
explicitFocusOrder="0" pos="8 88 136 40" bgColOff="ffff5c5c"
textCol="ff000000" buttonText="Record" connectedEdges="0" needsCallback="1"
radioGroupId="0"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,80 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 19 Sep 2009 12:36:23 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__
#define __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
#include "AudioDemoTabComponent.h"
class AudioRecorder;
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Jucer.
Describe your class and how it works here!
//[/Comments]
*/
class AudioDemoRecordPage : public Component,
public ButtonListener
{
public:
//==============================================================================
AudioDemoRecordPage (AudioDeviceManager& deviceManager_);
~AudioDemoRecordPage();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
//[/UserMethods]
void paint (Graphics& g);
void resized();
void buttonClicked (Button* buttonThatWasClicked);
void visibilityChanged();
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager;
AudioRecorder* recorder;
//[/UserVariables]
//==============================================================================
LiveAudioInputDisplayComp* liveAudioDisplayComp;
Label* explanationLabel;
TextButton* recordButton;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoRecordPage (const AudioDemoRecordPage&);
const AudioDemoRecordPage& operator= (const AudioDemoRecordPage&);
};
#endif // __JUCER_HEADER_AUDIODEMORECORDPAGE_AUDIODEMORECORDPAGE_9632FFAA__

View file

@ -0,0 +1,105 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 11:26:45 am
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoSetupPage.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
//[/MiscUserDefs]
//==============================================================================
AudioDemoSetupPage::AudioDemoSetupPage (AudioDeviceManager& deviceManager_)
: deviceManager (deviceManager_),
deviceSelector (0)
{
addAndMakeVisible (deviceSelector = new AudioDeviceSelectorComponent (deviceManager, 0, 2, 0, 2, true, true, true, false));
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
//[/Constructor]
}
AudioDemoSetupPage::~AudioDemoSetupPage()
{
//[Destructor_pre]. You can add your own custom destruction code here..
//[/Destructor_pre]
deleteAndZero (deviceSelector);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoSetupPage::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::lightgrey);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoSetupPage::resized()
{
deviceSelector->setBounds (8, 8, getWidth() - 16, getHeight() - 16);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoSetupPage" componentName=""
parentClasses="public Component" constructorParams="AudioDeviceManager&amp; deviceManager_"
variableInitialisers="deviceManager (deviceManager_)" snapPixels="8"
snapActive="1" snapShown="1" overlayOpacity="0.330000013" fixedSize="0"
initialWidth="600" initialHeight="400">
<BACKGROUND backgroundColour="ffd3d3d3"/>
<GENERICCOMPONENT name="" id="a04c56de9f3fc537" memberName="deviceSelector" virtualName=""
explicitFocusOrder="0" pos="8 8 16M 16M" class="AudioDeviceSelectorComponent"
params="deviceManager, 0, 2, 0, 2, true, true, true, false"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,72 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 11:26:45 am
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMOSETUPPAGE_AUDIODEMOSETUPPAGE_244CE6A7__
#define __JUCER_HEADER_AUDIODEMOSETUPPAGE_AUDIODEMOSETUPPAGE_244CE6A7__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Jucer.
Describe your class and how it works here!
//[/Comments]
*/
class AudioDemoSetupPage : public Component
{
public:
//==============================================================================
AudioDemoSetupPage (AudioDeviceManager& deviceManager_);
~AudioDemoSetupPage();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
//[/UserMethods]
void paint (Graphics& g);
void resized();
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager;
//[/UserVariables]
//==============================================================================
AudioDeviceSelectorComponent* deviceSelector;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoSetupPage (const AudioDemoSetupPage&);
const AudioDemoSetupPage& operator= (const AudioDemoSetupPage&);
};
#endif // __JUCER_HEADER_AUDIODEMOSETUPPAGE_AUDIODEMOSETUPPAGE_244CE6A7__

View file

@ -0,0 +1,393 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 9:46:49 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoSynthPage.h"
//[MiscUserDefs]
//==============================================================================
/** Our demo synth sound is just a basic sine wave..
*/
class SineWaveSound : public SynthesiserSound
{
public:
SineWaveSound()
{
}
bool appliesToNote (const int midiNoteNumber) { return true; }
bool appliesToChannel (const int midiChannel) { return true; }
};
//==============================================================================
/** Our demo synth voice just plays a sine wave..
*/
class SineWaveVoice : public SynthesiserVoice
{
public:
SineWaveVoice()
: angleDelta (0.0),
tailOff (0.0)
{
}
bool canPlaySound (SynthesiserSound* sound)
{
return dynamic_cast <SineWaveSound*> (sound) != 0;
}
void startNote (const int midiNoteNumber, const float velocity,
SynthesiserSound* sound, const int currentPitchWheelPosition)
{
currentAngle = 0.0;
level = velocity * 0.15;
tailOff = 0.0;
double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
double cyclesPerSample = cyclesPerSecond / getSampleRate();
angleDelta = cyclesPerSample * 2.0 * double_Pi;
}
void stopNote (const bool allowTailOff)
{
if (allowTailOff)
{
// start a tail-off by setting this flag. The render callback will pick up on
// this and do a fade out, calling clearCurrentNote() when it's finished.
if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
// stopNote method could be called more than once.
tailOff = 1.0;
}
else
{
// we're being told to stop playing immediately, so reset everything..
clearCurrentNote();
angleDelta = 0.0;
}
}
void pitchWheelMoved (const int newValue)
{
// can't be bothered implementing this for the demo!
}
void controllerMoved (const int controllerNumber, const int newValue)
{
// not interested in controllers in this case.
}
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
if (angleDelta != 0.0)
{
if (tailOff > 0)
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level * tailOff);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
tailOff *= 0.99;
if (tailOff <= 0.005)
{
clearCurrentNote();
angleDelta = 0.0;
break;
}
}
}
else
{
while (--numSamples >= 0)
{
const float currentSample = (float) (sin (currentAngle) * level);
for (int i = outputBuffer.getNumChannels(); --i >= 0;)
*outputBuffer.getSampleData (i, startSample) += currentSample;
currentAngle += angleDelta;
++startSample;
}
}
}
}
private:
double currentAngle, angleDelta, level, tailOff;
};
// This is an audio source that streams the output of our demo synth.
class SynthAudioSource : public AudioSource
{
public:
//==============================================================================
// this collects real-time midi messages from the midi input device, and
// turns them into blocks that we can process in our audio callback
MidiMessageCollector midiCollector;
// this represents the state of which keys on our on-screen keyboard are held
// down. When the mouse is clicked on the keyboard component, this object also
// generates midi messages for this, which we can pass on to our synth.
MidiKeyboardState& keyboardState;
// the synth itself!
Synthesiser synth;
//==============================================================================
SynthAudioSource (MidiKeyboardState& keyboardState_)
: keyboardState (keyboardState_)
{
// add some voices to our synth, to play the sounds..
for (int i = 4; --i >= 0;)
{
synth.addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds..
synth.addVoice (new SamplerVoice()); // and these ones play the sampled sounds
}
// and add some sounds for them to play...
setUsingSineWaveSound();
}
void setUsingSineWaveSound()
{
synth.clearSounds();
synth.addSound (new SineWaveSound());
}
void setUsingSampledSound()
{
synth.clearSounds();
WavAudioFormat wavFormat;
AudioFormatReader* audioReader
= wavFormat.createReaderFor (new MemoryInputStream (BinaryData::cello_wav,
BinaryData::cello_wavSize,
false),
true);
BitArray allNotes;
allNotes.setRange (0, 128, true);
synth.addSound (new SamplerSound (T("demo sound"),
*audioReader,
allNotes,
74, // root midi note
0.1, // attack time
0.1, // release time
10.0 // maximum sample length
));
delete audioReader;
}
void prepareToPlay (int samplesPerBlockExpected,
double sampleRate)
{
midiCollector.reset (sampleRate);
synth.setCurrentPlaybackSampleRate (sampleRate);
}
void releaseResources()
{
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
// the synth always adds its output to the audio buffer, so we have to clear it
// first..
bufferToFill.clearActiveBufferRegion();
// fill a midi buffer with incoming messages from the midi input.
MidiBuffer incomingMidi;
midiCollector.removeNextBlockOfMessages (incomingMidi, bufferToFill.numSamples);
// pass these messages to the keyboard state so that it can update the component
// to show on-screen which keys are being pressed on the physical midi keyboard.
// This call will also add midi messages to the buffer which were generated by
// the mouse-clicking on the on-screen keyboard.
keyboardState.processNextMidiBuffer (incomingMidi, 0, bufferToFill.numSamples, true);
// and now get the synth to process the midi events and generate its output.
synth.renderNextBlock (*bufferToFill.buffer, incomingMidi, 0, bufferToFill.numSamples);
}
};
//[/MiscUserDefs]
//==============================================================================
AudioDemoSynthPage::AudioDemoSynthPage (AudioDeviceManager& deviceManager_)
: deviceManager (deviceManager_),
keyboardComponent (0),
sineButton (0),
sampledButton (0),
liveAudioDisplayComp (0)
{
addAndMakeVisible (keyboardComponent = new MidiKeyboardComponent (keyboardState, MidiKeyboardComponent::horizontalKeyboard));
addAndMakeVisible (sineButton = new ToggleButton (String::empty));
sineButton->setButtonText (T("Use sine wave"));
sineButton->setRadioGroupId (321);
sineButton->addButtonListener (this);
sineButton->setToggleState (true, false);
addAndMakeVisible (sampledButton = new ToggleButton (String::empty));
sampledButton->setButtonText (T("Use sampled sound"));
sampledButton->setRadioGroupId (321);
sampledButton->addButtonListener (this);
addAndMakeVisible (liveAudioDisplayComp = new LiveAudioInputDisplayComp());
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
deviceManager.addAudioCallback (liveAudioDisplayComp);
synthAudioSource = new SynthAudioSource (keyboardState);
audioSourcePlayer.setSource (synthAudioSource);
deviceManager.addAudioCallback (&audioSourcePlayer);
deviceManager.addMidiInputCallback (String::empty, &(synthAudioSource->midiCollector));
//[/Constructor]
}
AudioDemoSynthPage::~AudioDemoSynthPage()
{
//[Destructor_pre]. You can add your own custom destruction code here..
audioSourcePlayer.setSource (0);
deviceManager.removeMidiInputCallback (String::empty, &(synthAudioSource->midiCollector));
deviceManager.removeAudioCallback (&audioSourcePlayer);
deviceManager.removeAudioCallback (liveAudioDisplayComp);
delete synthAudioSource;
//[/Destructor_pre]
deleteAndZero (keyboardComponent);
deleteAndZero (sineButton);
deleteAndZero (sampledButton);
deleteAndZero (liveAudioDisplayComp);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoSynthPage::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::lightgrey);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoSynthPage::resized()
{
keyboardComponent->setBounds (8, 96, getWidth() - 16, 64);
sineButton->setBounds (16, 176, 150, 24);
sampledButton->setBounds (16, 200, 150, 24);
liveAudioDisplayComp->setBounds (8, 8, getWidth() - 16, 64);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
void AudioDemoSynthPage::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == sineButton)
{
//[UserButtonCode_sineButton] -- add your button handler code here..
synthAudioSource->setUsingSineWaveSound();
//[/UserButtonCode_sineButton]
}
else if (buttonThatWasClicked == sampledButton)
{
//[UserButtonCode_sampledButton] -- add your button handler code here..
synthAudioSource->setUsingSampledSound();
//[/UserButtonCode_sampledButton]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoSynthPage" componentName=""
parentClasses="public Component" constructorParams="AudioDeviceManager&amp; deviceManager_"
variableInitialisers="deviceManager (deviceManager_)" snapPixels="8"
snapActive="1" snapShown="1" overlayOpacity="0.330000013" fixedSize="0"
initialWidth="600" initialHeight="400">
<BACKGROUND backgroundColour="ffd3d3d3"/>
<GENERICCOMPONENT name="" id="86605ec4f02c4320" memberName="keyboardComponent"
virtualName="" explicitFocusOrder="0" pos="8 96 16M 64" class="MidiKeyboardComponent"
params="keyboardState, MidiKeyboardComponent::horizontalKeyboard"/>
<TOGGLEBUTTON name="" id="d75101df45006ba9" memberName="sineButton" virtualName=""
explicitFocusOrder="0" pos="16 176 150 24" buttonText="Use sine wave"
connectedEdges="0" needsCallback="1" radioGroupId="321" state="1"/>
<TOGGLEBUTTON name="" id="2d687b4ac3dad628" memberName="sampledButton" virtualName=""
explicitFocusOrder="0" pos="16 200 150 24" buttonText="Use sampled sound"
connectedEdges="0" needsCallback="1" radioGroupId="321" state="0"/>
<GENERICCOMPONENT name="" id="7d70eb2617f56220" memberName="liveAudioDisplayComp"
virtualName="" explicitFocusOrder="0" pos="8 8 16M 64" class="LiveAudioInputDisplayComp"
params=""/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,82 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 18 Sep 2009 9:46:49 pm
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMOSYNTHPAGE_AUDIODEMOSYNTHPAGE_76557DC7__
#define __JUCER_HEADER_AUDIODEMOSYNTHPAGE_AUDIODEMOSYNTHPAGE_76557DC7__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
#include "AudioDemoTabComponent.h"
class SynthAudioSource;
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Jucer.
Describe your class and how it works here!
//[/Comments]
*/
class AudioDemoSynthPage : public Component,
public ButtonListener
{
public:
//==============================================================================
AudioDemoSynthPage (AudioDeviceManager& deviceManager_);
~AudioDemoSynthPage();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
//[/UserMethods]
void paint (Graphics& g);
void resized();
void buttonClicked (Button* buttonThatWasClicked);
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager;
MidiKeyboardState keyboardState;
AudioSourcePlayer audioSourcePlayer;
SynthAudioSource* synthAudioSource;
//[/UserVariables]
//==============================================================================
MidiKeyboardComponent* keyboardComponent;
ToggleButton* sineButton;
ToggleButton* sampledButton;
LiveAudioInputDisplayComp* liveAudioDisplayComp;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoSynthPage (const AudioDemoSynthPage&);
const AudioDemoSynthPage& operator= (const AudioDemoSynthPage&);
};
#endif // __JUCER_HEADER_AUDIODEMOSYNTHPAGE_AUDIODEMOSYNTHPAGE_76557DC7__

View file

@ -0,0 +1,210 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 19 Sep 2009 11:10:57 am
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "AudioDemoTabComponent.h"
#include "AudioDemoSetupPage.h"
#include "AudioDemoPlaybackPage.h"
#include "AudioDemoSynthPage.h"
#include "AudioDemoLatencyPage.h"
#include "AudioDemoRecordPage.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
LiveAudioInputDisplayComp::LiveAudioInputDisplayComp()
{
nextSample = subSample = 0;
accumulator = 0;
zeromem (samples, sizeof (samples));
setOpaque (true);
startTimer (1000 / 50); // use a timer to keep repainting this component
}
LiveAudioInputDisplayComp::~LiveAudioInputDisplayComp()
{
}
void LiveAudioInputDisplayComp::paint (Graphics& g)
{
g.fillAll (Colours::black);
g.setColour (Colours::green);
const float midY = getHeight() * 0.5f;
int sampleNum = (nextSample + numElementsInArray (samples) - 1);
for (int x = jmin (getWidth(), numElementsInArray (samples)); --x >= 0;)
{
const float sampleSize = midY * samples [sampleNum-- % numElementsInArray (samples)];
g.drawVerticalLine (x, midY - sampleSize, midY + sampleSize);
}
}
void LiveAudioInputDisplayComp::timerCallback()
{
repaint();
}
void LiveAudioInputDisplayComp::audioDeviceAboutToStart (AudioIODevice* device)
{
zeromem (samples, sizeof (samples));
}
void LiveAudioInputDisplayComp::audioDeviceStopped()
{
zeromem (samples, sizeof (samples));
}
void LiveAudioInputDisplayComp::audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, int numSamples)
{
for (int i = 0; i < numSamples; ++i)
{
for (int chan = 0; chan < numInputChannels; ++chan)
{
if (inputChannelData[chan] != 0)
accumulator += fabsf (inputChannelData[chan][i]);
}
const int numSubSamples = 100; // how many input samples go onto one pixel.
const float boost = 10.0f; // how much to boost the levels to make it more visible.
if (subSample == 0)
{
samples[nextSample] = accumulator * boost / numSubSamples;
nextSample = (nextSample + 1) % numElementsInArray (samples);
subSample = numSubSamples;
accumulator = 0;
}
else
{
--subSample;
}
}
// We need to clear the output buffers, in case they're full of junk..
for (int i = 0; i < numOutputChannels; ++i)
if (outputChannelData[i] != 0)
zeromem (outputChannelData[i], sizeof (float) * numSamples);
}
//[/MiscUserDefs]
//==============================================================================
AudioDemoTabComponent::AudioDemoTabComponent ()
: tabbedComponent (0)
{
addAndMakeVisible (tabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop));
tabbedComponent->setTabBarDepth (30);
tabbedComponent->addTab (T("Audio Device Setup"), Colours::lightgrey, new AudioDemoSetupPage (deviceManager), true);
tabbedComponent->addTab (T("File Playback"), Colours::lightgrey, new AudioDemoPlaybackPage (deviceManager), true);
tabbedComponent->addTab (T("Synth Playback"), Colours::lightgrey, new AudioDemoSynthPage (deviceManager), true);
tabbedComponent->addTab (T("Latency Test"), Colours::lightgrey, new AudioDemoLatencyPage (deviceManager), true);
tabbedComponent->addTab (T("Recording"), Colours::lightgrey, new AudioDemoRecordPage (deviceManager), true);
tabbedComponent->setCurrentTabIndex (0);
//[UserPreSize]
deviceManager.initialise (2, 2, 0, true, String::empty, 0);
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
//[/Constructor]
}
AudioDemoTabComponent::~AudioDemoTabComponent()
{
//[Destructor_pre]. You can add your own custom destruction code here..
//[/Destructor_pre]
deleteAndZero (tabbedComponent);
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void AudioDemoTabComponent::paint (Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (Colours::white);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void AudioDemoTabComponent::resized()
{
tabbedComponent->setBounds (0, 0, getWidth() - 0, getHeight() - 0);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
//==============================================================================
Component* createAudioDemo()
{
return new AudioDemoTabComponent();
}
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Jucer information section --
This is where the Jucer puts all of its metadata, so don't change anything in here!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="AudioDemoTabComponent" componentName=""
parentClasses="public Component" constructorParams="" variableInitialisers=""
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330000013"
fixedSize="0" initialWidth="600" initialHeight="400">
<BACKGROUND backgroundColour="ffffffff"/>
<TABBEDCOMPONENT name="new tabbed component" id="83c980d7793cdced" memberName="tabbedComponent"
virtualName="" explicitFocusOrder="0" pos="0 0 0M 0M" orientation="top"
tabBarDepth="30" initialTab="0">
<TAB name="Audio Device Setup" colour="ffd3d3d3" useJucerComp="1"
contentClassName="" constructorParams="deviceManager" jucerComponentFile="AudioDemoSetupPage.cpp"/>
<TAB name="File Playback" colour="ffd3d3d3" useJucerComp="1" contentClassName=""
constructorParams="deviceManager" jucerComponentFile="AudioDemoPlaybackPage.cpp"/>
<TAB name="Synth Playback" colour="ffd3d3d3" useJucerComp="1" contentClassName=""
constructorParams="deviceManager" jucerComponentFile="AudioDemoSynthPage.cpp"/>
<TAB name="Latency Test" colour="ffd3d3d3" useJucerComp="1" contentClassName=""
constructorParams="deviceManager" jucerComponentFile="AudioDemoLatencyPage.cpp"/>
<TAB name="Recording" colour="ffd3d3d3" useJucerComp="1" contentClassName=""
constructorParams="deviceManager" jucerComponentFile="AudioDemoRecordPage.cpp"/>
</TABBEDCOMPONENT>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif

View file

@ -0,0 +1,102 @@
/*
==============================================================================
This is an automatically generated file created by the Jucer!
Creation date: 19 Sep 2009 11:10:57 am
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Jucer version: 1.12
------------------------------------------------------------------------------
The Jucer is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-6 by Raw Material Software ltd.
==============================================================================
*/
#ifndef __JUCER_HEADER_AUDIODEMOTABCOMPONENT_AUDIODEMOTABCOMPONENT_10720733__
#define __JUCER_HEADER_AUDIODEMOTABCOMPONENT_AUDIODEMOTABCOMPONENT_10720733__
//[Headers] -- You can add your own extra header files here --
#include "../jucedemo_headers.h"
//==============================================================================
/* This component scrolls a continuous waveform showing the audio that's currently
coming into the audio input.
*/
class LiveAudioInputDisplayComp : public Component,
public AudioIODeviceCallback,
public Timer
{
public:
//==============================================================================
LiveAudioInputDisplayComp();
~LiveAudioInputDisplayComp();
void paint (Graphics& g);
void timerCallback();
void audioDeviceAboutToStart (AudioIODevice* device);
void audioDeviceStopped();
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels, int numSamples);
private:
float samples [1024];
int nextSample, subSample;
float accumulator;
LiveAudioInputDisplayComp (const LiveAudioInputDisplayComp&);
const LiveAudioInputDisplayComp& operator= (const LiveAudioInputDisplayComp&);
};
//[/Headers]
//==============================================================================
/**
//[Comments]
This component creates the set of tabs that hold the various
audio demo pages..
//[/Comments]
*/
class AudioDemoTabComponent : public Component
{
public:
//==============================================================================
AudioDemoTabComponent ();
~AudioDemoTabComponent();
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
//[/UserMethods]
void paint (Graphics& g);
void resized();
//==============================================================================
juce_UseDebuggingNewOperator
private:
//[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager deviceManager;
//[/UserVariables]
//==============================================================================
TabbedComponent* tabbedComponent;
//==============================================================================
// (prevent copy constructor and operator= being generated..)
AudioDemoTabComponent (const AudioDemoTabComponent&);
const AudioDemoTabComponent& operator= (const AudioDemoTabComponent&);
};
#endif // __JUCER_HEADER_AUDIODEMOTABCOMPONENT_AUDIODEMOTABCOMPONENT_10720733__

View file

@ -41,8 +41,10 @@
//#define JUCE_ONLY_BUILD_CORE_LIBRARY 1
//#define JUCE_FORCE_DEBUG 1
//#define JUCE_LOG_ASSERTIONS 1
#define JUCE_WASAPI 1
//#define JUCE_ASIO 1
//#define JUCE_ALSA 1
#ifdef _MSC_VER
#define JUCE_QUICKTIME 0 // (This is disabled here by default because on windows it requires the QT SDK,
// but you can turn it on again if you've got the SDK)

View file

@ -232850,6 +232850,9 @@ const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType typ
switch (type)
{
case userHomeDirectory:
csidlType = CSIDL_PROFILE;
break;
case userDocumentsDirectory:
csidlType = CSIDL_PERSONAL;
break;

View file

@ -450,6 +450,9 @@ const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType typ
switch (type)
{
case userHomeDirectory:
csidlType = CSIDL_PROFILE;
break;
case userDocumentsDirectory:
csidlType = CSIDL_PERSONAL;
break;