Browse Source

New class AbstractFifo - a lock-free fifo helper class. New class AudioFormatWriter::ThreadedWriter, which helps stream an audio file to disk on a background thread. Simplified the juce demo audio recorder using this new class.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
0e2e4e7c3a
27 changed files with 2122 additions and 1293 deletions
  1. +18
    -0
      Builds/Linux/Makefile
  2. +14
    -0
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  3. +4
    -0
      Builds/VisualStudio2005/Juce.vcproj
  4. +4
    -0
      Builds/VisualStudio2008/Juce.vcproj
  5. +4
    -0
      Builds/VisualStudio2008_DLL/Juce.vcproj
  6. +4
    -0
      Builds/VisualStudio2010/Juce.vcxproj
  7. +12
    -0
      Builds/VisualStudio2010/Juce.vcxproj.filters
  8. +14
    -0
      Builds/iPhone/Juce.xcodeproj/project.pbxproj
  9. +8
    -0
      Juce.jucer
  10. +3
    -0
      amalgamation/juce_amalgamated_template.cpp
  11. +1
    -1
      extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h
  12. +49
    -150
      extras/juce demo/Source/demos/AudioDemoRecordPage.cpp
  13. +1
    -1
      extras/juce demo/Source/demos/AudioDemoRecordPage.h
  14. +270
    -157
      juce_amalgamated.cpp
  15. +655
    -409
      juce_amalgamated.h
  16. +2
    -2
      src/audio/audio_file_formats/juce_AiffAudioFormat.cpp
  17. +5
    -496
      src/audio/audio_file_formats/juce_AudioFormat.cpp
  18. +367
    -0
      src/audio/audio_file_formats/juce_AudioFormatReader.cpp
  19. +272
    -0
      src/audio/audio_file_formats/juce_AudioFormatWriter.cpp
  20. +57
    -2
      src/audio/audio_file_formats/juce_AudioFormatWriter.h
  21. +5
    -17
      src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp
  22. +4
    -18
      src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp
  23. +2
    -39
      src/audio/dsp/juce_AudioSampleBuffer.cpp
  24. +123
    -0
      src/containers/juce_AbstractFifo.cpp
  25. +220
    -0
      src/containers/juce_AbstractFifo.h
  26. +1
    -1
      src/core/juce_StandardHeader.h
  27. +3
    -0
      src/juce_core_includes.h

+ 18
- 0
Builds/Linux/Makefile View File

@@ -48,6 +48,8 @@ OBJECTS := \
$(OBJDIR)/juce_AudioCDReader_c730f7a6.o \ $(OBJDIR)/juce_AudioCDReader_c730f7a6.o \
$(OBJDIR)/juce_AudioFormat_6605d0f9.o \ $(OBJDIR)/juce_AudioFormat_6605d0f9.o \
$(OBJDIR)/juce_AudioFormatManager_949148fe.o \ $(OBJDIR)/juce_AudioFormatManager_949148fe.o \
$(OBJDIR)/juce_AudioFormatReader_36f0295c.o \
$(OBJDIR)/juce_AudioFormatWriter_11461d0c.o \
$(OBJDIR)/juce_AudioSubsectionReader_65f61a0a.o \ $(OBJDIR)/juce_AudioSubsectionReader_65f61a0a.o \
$(OBJDIR)/juce_AudioThumbnail_cb99b4b4.o \ $(OBJDIR)/juce_AudioThumbnail_cb99b4b4.o \
$(OBJDIR)/juce_AudioThumbnailCache_89a7c678.o \ $(OBJDIR)/juce_AudioThumbnailCache_89a7c678.o \
@@ -92,6 +94,7 @@ OBJECTS := \
$(OBJDIR)/juce_GenericAudioProcessorEditor_2e8ec30d.o \ $(OBJDIR)/juce_GenericAudioProcessorEditor_2e8ec30d.o \
$(OBJDIR)/juce_Sampler_98f716a4.o \ $(OBJDIR)/juce_Sampler_98f716a4.o \
$(OBJDIR)/juce_Synthesiser_2bffa1dd.o \ $(OBJDIR)/juce_Synthesiser_2bffa1dd.o \
$(OBJDIR)/juce_AbstractFifo_dfc0bd23.o \
$(OBJDIR)/juce_BigInteger_63589133.o \ $(OBJDIR)/juce_BigInteger_63589133.o \
$(OBJDIR)/juce_DynamicObject_69d02ab3.o \ $(OBJDIR)/juce_DynamicObject_69d02ab3.o \
$(OBJDIR)/juce_Expression_1e9a5aad.o \ $(OBJDIR)/juce_Expression_1e9a5aad.o \
@@ -404,6 +407,16 @@ $(OBJDIR)/juce_AudioFormatManager_949148fe.o: ../../src/audio/audio_file_formats
@echo "Compiling juce_AudioFormatManager.cpp" @echo "Compiling juce_AudioFormatManager.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_AudioFormatReader_36f0295c.o: ../../src/audio/audio_file_formats/juce_AudioFormatReader.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling juce_AudioFormatReader.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_AudioFormatWriter_11461d0c.o: ../../src/audio/audio_file_formats/juce_AudioFormatWriter.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling juce_AudioFormatWriter.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_AudioSubsectionReader_65f61a0a.o: ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp $(OBJDIR)/juce_AudioSubsectionReader_65f61a0a.o: ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp
-@mkdir -p $(OBJDIR) -@mkdir -p $(OBJDIR)
@echo "Compiling juce_AudioSubsectionReader.cpp" @echo "Compiling juce_AudioSubsectionReader.cpp"
@@ -624,6 +637,11 @@ $(OBJDIR)/juce_Synthesiser_2bffa1dd.o: ../../src/audio/synthesisers/juce_Synthes
@echo "Compiling juce_Synthesiser.cpp" @echo "Compiling juce_Synthesiser.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_AbstractFifo_dfc0bd23.o: ../../src/containers/juce_AbstractFifo.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling juce_AbstractFifo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_BigInteger_63589133.o: ../../src/containers/juce_BigInteger.cpp $(OBJDIR)/juce_BigInteger_63589133.o: ../../src/containers/juce_BigInteger.cpp
-@mkdir -p $(OBJDIR) -@mkdir -p $(OBJDIR)
@echo "Compiling juce_BigInteger.cpp" @echo "Compiling juce_BigInteger.cpp"


+ 14
- 0
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -15,6 +15,8 @@
983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; }; 983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; };
416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; }; 416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; };
9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; }; 9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; };
992F46189ABF711A047186A4 = { isa = PBXBuildFile; fileRef = 9349E14552FEA0371553E808; };
5C312E6678456C8293633E0F = { isa = PBXBuildFile; fileRef = 2AD64F53E12B20011B7A0DB7; };
FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; }; FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; };
C1147D03F1F4D697CC30DD22 = { isa = PBXBuildFile; fileRef = 27C3C51DF2519B519B76E2EE; }; C1147D03F1F4D697CC30DD22 = { isa = PBXBuildFile; fileRef = 27C3C51DF2519B519B76E2EE; };
C5CFF5508299C26380465290 = { isa = PBXBuildFile; fileRef = CB32D4EE59D5CA9DB12F944D; }; C5CFF5508299C26380465290 = { isa = PBXBuildFile; fileRef = CB32D4EE59D5CA9DB12F944D; };
@@ -61,6 +63,7 @@
D1407BB28C169F5E1CAC3CC7 = { isa = PBXBuildFile; fileRef = 096CF2243648F17E1BF5421B; }; D1407BB28C169F5E1CAC3CC7 = { isa = PBXBuildFile; fileRef = 096CF2243648F17E1BF5421B; };
07E6E11A658930554FF0C56A = { isa = PBXBuildFile; fileRef = ED5966B95F865C586A3CE08F; }; 07E6E11A658930554FF0C56A = { isa = PBXBuildFile; fileRef = ED5966B95F865C586A3CE08F; };
E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; }; E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; };
1F905F44E5FA23A2D5CCDA0A = { isa = PBXBuildFile; fileRef = 4F22276689685D839BD252EA; };
BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; }; BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; };
4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; }; 4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; };
25018C91F79D918FEA084630 = { isa = PBXBuildFile; fileRef = 199DFD1C5A282FE13A585FEA; }; 25018C91F79D918FEA084630 = { isa = PBXBuildFile; fileRef = 199DFD1C5A282FE13A585FEA; };
@@ -359,7 +362,9 @@
013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; }; 013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; };
93006D32B18174D9FE0A5E9E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatManager.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp; sourceTree = SOURCE_ROOT; }; 93006D32B18174D9FE0A5E9E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatManager.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp; sourceTree = SOURCE_ROOT; };
41070806F82EC9C6D1C67689 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatManager.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.h; sourceTree = SOURCE_ROOT; }; 41070806F82EC9C6D1C67689 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatManager.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.h; sourceTree = SOURCE_ROOT; };
9349E14552FEA0371553E808 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.cpp; sourceTree = SOURCE_ROOT; };
27356F5E93CEA4D472D83D8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatReader.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.h; sourceTree = SOURCE_ROOT; }; 27356F5E93CEA4D472D83D8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatReader.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.h; sourceTree = SOURCE_ROOT; };
2AD64F53E12B20011B7A0DB7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatWriter.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.cpp; sourceTree = SOURCE_ROOT; };
8BD38C2507C0F8E28930A4F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatWriter.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.h; sourceTree = SOURCE_ROOT; }; 8BD38C2507C0F8E28930A4F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatWriter.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.h; sourceTree = SOURCE_ROOT; };
59597FA0A88A08937801D198 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioSubsectionReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp; sourceTree = SOURCE_ROOT; }; 59597FA0A88A08937801D198 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioSubsectionReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp; sourceTree = SOURCE_ROOT; };
AE7F7F0D959C2E3CF5989C88 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioSubsectionReader.h; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.h; sourceTree = SOURCE_ROOT; }; AE7F7F0D959C2E3CF5989C88 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioSubsectionReader.h; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.h; sourceTree = SOURCE_ROOT; };
@@ -477,6 +482,8 @@
6C6C1C360138D9BD4B27588B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Sampler.h; path = ../../src/audio/synthesisers/juce_Sampler.h; sourceTree = SOURCE_ROOT; }; 6C6C1C360138D9BD4B27588B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Sampler.h; path = ../../src/audio/synthesisers/juce_Sampler.h; sourceTree = SOURCE_ROOT; };
35668D8EEA19957C6C9AC83A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Synthesiser.cpp; path = ../../src/audio/synthesisers/juce_Synthesiser.cpp; sourceTree = SOURCE_ROOT; }; 35668D8EEA19957C6C9AC83A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Synthesiser.cpp; path = ../../src/audio/synthesisers/juce_Synthesiser.cpp; sourceTree = SOURCE_ROOT; };
9E6C206F95245BCDE38FB2B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Synthesiser.h; path = ../../src/audio/synthesisers/juce_Synthesiser.h; sourceTree = SOURCE_ROOT; }; 9E6C206F95245BCDE38FB2B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Synthesiser.h; path = ../../src/audio/synthesisers/juce_Synthesiser.h; sourceTree = SOURCE_ROOT; };
4F22276689685D839BD252EA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AbstractFifo.cpp; path = ../../src/containers/juce_AbstractFifo.cpp; sourceTree = SOURCE_ROOT; };
9584B84F23A4251755D49213 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AbstractFifo.h; path = ../../src/containers/juce_AbstractFifo.h; sourceTree = SOURCE_ROOT; };
839BE8047CF2F8EBE43ED34F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Array.h; path = ../../src/containers/juce_Array.h; sourceTree = SOURCE_ROOT; }; 839BE8047CF2F8EBE43ED34F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Array.h; path = ../../src/containers/juce_Array.h; sourceTree = SOURCE_ROOT; };
EDF52FDF87ACD33FE933142C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrayAllocationBase.h; path = ../../src/containers/juce_ArrayAllocationBase.h; sourceTree = SOURCE_ROOT; }; EDF52FDF87ACD33FE933142C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrayAllocationBase.h; path = ../../src/containers/juce_ArrayAllocationBase.h; sourceTree = SOURCE_ROOT; };
895D742F49DA9F100990879C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_BigInteger.cpp; path = ../../src/containers/juce_BigInteger.cpp; sourceTree = SOURCE_ROOT; }; 895D742F49DA9F100990879C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_BigInteger.cpp; path = ../../src/containers/juce_BigInteger.cpp; sourceTree = SOURCE_ROOT; };
@@ -1048,7 +1055,9 @@
013E8938EE1C6B4F63016B55, 013E8938EE1C6B4F63016B55,
93006D32B18174D9FE0A5E9E, 93006D32B18174D9FE0A5E9E,
41070806F82EC9C6D1C67689, 41070806F82EC9C6D1C67689,
9349E14552FEA0371553E808,
27356F5E93CEA4D472D83D8E, 27356F5E93CEA4D472D83D8E,
2AD64F53E12B20011B7A0DB7,
8BD38C2507C0F8E28930A4F8, 8BD38C2507C0F8E28930A4F8,
59597FA0A88A08937801D198, 59597FA0A88A08937801D198,
AE7F7F0D959C2E3CF5989C88, AE7F7F0D959C2E3CF5989C88,
@@ -1195,6 +1204,8 @@
231431F8B23F01DC6ECD4214, 231431F8B23F01DC6ECD4214,
DC641C77950A335A20FD4532 ); name = audio; sourceTree = "<group>"; }; DC641C77950A335A20FD4532 ); name = audio; sourceTree = "<group>"; };
1CC2889DB696E12FC34E3F50 = { isa = PBXGroup; children = ( 1CC2889DB696E12FC34E3F50 = { isa = PBXGroup; children = (
4F22276689685D839BD252EA,
9584B84F23A4251755D49213,
839BE8047CF2F8EBE43ED34F, 839BE8047CF2F8EBE43ED34F,
EDF52FDF87ACD33FE933142C, EDF52FDF87ACD33FE933142C,
895D742F49DA9F100990879C, 895D742F49DA9F100990879C,
@@ -1915,6 +1926,8 @@
983FCD60625A60993546F850, 983FCD60625A60993546F850,
416D6F00E88DC74879B4DF2B, 416D6F00E88DC74879B4DF2B,
9C709BC2F4F0EE60BF52FACA, 9C709BC2F4F0EE60BF52FACA,
992F46189ABF711A047186A4,
5C312E6678456C8293633E0F,
FB21B7E6A7CE55D3C0E3C37E, FB21B7E6A7CE55D3C0E3C37E,
C1147D03F1F4D697CC30DD22, C1147D03F1F4D697CC30DD22,
C5CFF5508299C26380465290, C5CFF5508299C26380465290,
@@ -1961,6 +1974,7 @@
D1407BB28C169F5E1CAC3CC7, D1407BB28C169F5E1CAC3CC7,
07E6E11A658930554FF0C56A, 07E6E11A658930554FF0C56A,
E8DFABC1603D55B97429A8E4, E8DFABC1603D55B97429A8E4,
1F905F44E5FA23A2D5CCDA0A,
BE25871C34D79FEFFD1B94B6, BE25871C34D79FEFFD1B94B6,
4AB5E55BDF79028F82F83D8E, 4AB5E55BDF79028F82F83D8E,
25018C91F79D918FEA084630, 25018C91F79D918FEA084630,


+ 4
- 0
Builds/VisualStudio2005/Juce.vcproj View File

@@ -124,7 +124,9 @@
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/>
@@ -343,6 +345,8 @@
</Filter> </Filter>
</Filter> </Filter>
<Filter Name="containers"> <Filter Name="containers">
<File RelativePath="..\..\src\containers\juce_AbstractFifo.cpp"/>
<File RelativePath="..\..\src\containers\juce_AbstractFifo.h"/>
<File RelativePath="..\..\src\containers\juce_Array.h"/> <File RelativePath="..\..\src\containers\juce_Array.h"/>
<File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/> <File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/>
<File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/> <File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/>


+ 4
- 0
Builds/VisualStudio2008/Juce.vcproj View File

@@ -124,7 +124,9 @@
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/>
@@ -343,6 +345,8 @@
</Filter> </Filter>
</Filter> </Filter>
<Filter Name="containers"> <Filter Name="containers">
<File RelativePath="..\..\src\containers\juce_AbstractFifo.cpp"/>
<File RelativePath="..\..\src\containers\juce_AbstractFifo.h"/>
<File RelativePath="..\..\src\containers\juce_Array.h"/> <File RelativePath="..\..\src\containers\juce_Array.h"/>
<File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/> <File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/>
<File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/> <File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/>


+ 4
- 0
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -126,7 +126,9 @@
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormat.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.h"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/>
<File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/> <File RelativePath="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.h"/>
@@ -345,6 +347,8 @@
</Filter> </Filter>
</Filter> </Filter>
<Filter Name="containers"> <Filter Name="containers">
<File RelativePath="..\..\src\containers\juce_AbstractFifo.cpp"/>
<File RelativePath="..\..\src\containers\juce_AbstractFifo.h"/>
<File RelativePath="..\..\src\containers\juce_Array.h"/> <File RelativePath="..\..\src\containers\juce_Array.h"/>
<File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/> <File RelativePath="..\..\src\containers\juce_ArrayAllocationBase.h"/>
<File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/> <File RelativePath="..\..\src\containers\juce_BigInteger.cpp"/>


+ 4
- 0
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -131,6 +131,8 @@
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioCDReader.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormat.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioThumbnail.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioThumbnail.cpp"/>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioThumbnailCache.cpp"/> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioThumbnailCache.cpp"/>
@@ -175,6 +177,7 @@
<ClCompile Include="..\..\src\audio\processors\juce_GenericAudioProcessorEditor.cpp"/> <ClCompile Include="..\..\src\audio\processors\juce_GenericAudioProcessorEditor.cpp"/>
<ClCompile Include="..\..\src\audio\synthesisers\juce_Sampler.cpp"/> <ClCompile Include="..\..\src\audio\synthesisers\juce_Sampler.cpp"/>
<ClCompile Include="..\..\src\audio\synthesisers\juce_Synthesiser.cpp"/> <ClCompile Include="..\..\src\audio\synthesisers\juce_Synthesiser.cpp"/>
<ClCompile Include="..\..\src\containers\juce_AbstractFifo.cpp"/>
<ClCompile Include="..\..\src\containers\juce_BigInteger.cpp"/> <ClCompile Include="..\..\src\containers\juce_BigInteger.cpp"/>
<ClCompile Include="..\..\src\containers\juce_DynamicObject.cpp"/> <ClCompile Include="..\..\src\containers\juce_DynamicObject.cpp"/>
<ClCompile Include="..\..\src\containers\juce_Expression.cpp"/> <ClCompile Include="..\..\src\containers\juce_Expression.cpp"/>
@@ -500,6 +503,7 @@
<ClInclude Include="..\..\src\audio\processors\juce_GenericAudioProcessorEditor.h"/> <ClInclude Include="..\..\src\audio\processors\juce_GenericAudioProcessorEditor.h"/>
<ClInclude Include="..\..\src\audio\synthesisers\juce_Sampler.h"/> <ClInclude Include="..\..\src\audio\synthesisers\juce_Sampler.h"/>
<ClInclude Include="..\..\src\audio\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\src\audio\synthesisers\juce_Synthesiser.h"/>
<ClInclude Include="..\..\src\containers\juce_AbstractFifo.h"/>
<ClInclude Include="..\..\src\containers\juce_Array.h"/> <ClInclude Include="..\..\src\containers\juce_Array.h"/>
<ClInclude Include="..\..\src\containers\juce_ArrayAllocationBase.h"/> <ClInclude Include="..\..\src\containers\juce_ArrayAllocationBase.h"/>
<ClInclude Include="..\..\src\containers\juce_BigInteger.h"/> <ClInclude Include="..\..\src\containers\juce_BigInteger.h"/>


+ 12
- 0
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -202,6 +202,12 @@
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp"> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatManager.cpp">
<Filter>Juce\Source\audio\audio_file_formats</Filter> <Filter>Juce\Source\audio\audio_file_formats</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatReader.cpp">
<Filter>Juce\Source\audio\audio_file_formats</Filter>
</ClCompile>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioFormatWriter.cpp">
<Filter>Juce\Source\audio\audio_file_formats</Filter>
</ClCompile>
<ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp"> <ClCompile Include="..\..\src\audio\audio_file_formats\juce_AudioSubsectionReader.cpp">
<Filter>Juce\Source\audio\audio_file_formats</Filter> <Filter>Juce\Source\audio\audio_file_formats</Filter>
</ClCompile> </ClCompile>
@@ -373,6 +379,9 @@
<ClCompile Include="..\..\src\audio\synthesisers\juce_Synthesiser.cpp"> <ClCompile Include="..\..\src\audio\synthesisers\juce_Synthesiser.cpp">
<Filter>Juce\Source\audio\synthesisers</Filter> <Filter>Juce\Source\audio\synthesisers</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\containers\juce_AbstractFifo.cpp">
<Filter>Juce\Source\containers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\containers\juce_BigInteger.cpp"> <ClCompile Include="..\..\src\containers\juce_BigInteger.cpp">
<Filter>Juce\Source\containers</Filter> <Filter>Juce\Source\containers</Filter>
</ClCompile> </ClCompile>
@@ -1422,6 +1431,9 @@
<ClInclude Include="..\..\src\audio\synthesisers\juce_Synthesiser.h"> <ClInclude Include="..\..\src\audio\synthesisers\juce_Synthesiser.h">
<Filter>Juce\Source\audio\synthesisers</Filter> <Filter>Juce\Source\audio\synthesisers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\containers\juce_AbstractFifo.h">
<Filter>Juce\Source\containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\containers\juce_Array.h"> <ClInclude Include="..\..\src\containers\juce_Array.h">
<Filter>Juce\Source\containers</Filter> <Filter>Juce\Source\containers</Filter>
</ClInclude> </ClInclude>


+ 14
- 0
Builds/iPhone/Juce.xcodeproj/project.pbxproj View File

@@ -15,6 +15,8 @@
983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; }; 983FCD60625A60993546F850 = { isa = PBXBuildFile; fileRef = 0877D5750D6F21C5231687CA; };
416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; }; 416D6F00E88DC74879B4DF2B = { isa = PBXBuildFile; fileRef = 7D85530D76756C33795ECCE9; };
9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; }; 9C709BC2F4F0EE60BF52FACA = { isa = PBXBuildFile; fileRef = 93006D32B18174D9FE0A5E9E; };
992F46189ABF711A047186A4 = { isa = PBXBuildFile; fileRef = 9349E14552FEA0371553E808; };
5C312E6678456C8293633E0F = { isa = PBXBuildFile; fileRef = 2AD64F53E12B20011B7A0DB7; };
FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; }; FB21B7E6A7CE55D3C0E3C37E = { isa = PBXBuildFile; fileRef = 59597FA0A88A08937801D198; };
C1147D03F1F4D697CC30DD22 = { isa = PBXBuildFile; fileRef = 27C3C51DF2519B519B76E2EE; }; C1147D03F1F4D697CC30DD22 = { isa = PBXBuildFile; fileRef = 27C3C51DF2519B519B76E2EE; };
C5CFF5508299C26380465290 = { isa = PBXBuildFile; fileRef = CB32D4EE59D5CA9DB12F944D; }; C5CFF5508299C26380465290 = { isa = PBXBuildFile; fileRef = CB32D4EE59D5CA9DB12F944D; };
@@ -61,6 +63,7 @@
D1407BB28C169F5E1CAC3CC7 = { isa = PBXBuildFile; fileRef = 096CF2243648F17E1BF5421B; }; D1407BB28C169F5E1CAC3CC7 = { isa = PBXBuildFile; fileRef = 096CF2243648F17E1BF5421B; };
07E6E11A658930554FF0C56A = { isa = PBXBuildFile; fileRef = ED5966B95F865C586A3CE08F; }; 07E6E11A658930554FF0C56A = { isa = PBXBuildFile; fileRef = ED5966B95F865C586A3CE08F; };
E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; }; E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; };
1F905F44E5FA23A2D5CCDA0A = { isa = PBXBuildFile; fileRef = 4F22276689685D839BD252EA; };
BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; }; BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; };
4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; }; 4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; };
25018C91F79D918FEA084630 = { isa = PBXBuildFile; fileRef = 199DFD1C5A282FE13A585FEA; }; 25018C91F79D918FEA084630 = { isa = PBXBuildFile; fileRef = 199DFD1C5A282FE13A585FEA; };
@@ -359,7 +362,9 @@
013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; }; 013E8938EE1C6B4F63016B55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormat.h; path = ../../src/audio/audio_file_formats/juce_AudioFormat.h; sourceTree = SOURCE_ROOT; };
93006D32B18174D9FE0A5E9E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatManager.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp; sourceTree = SOURCE_ROOT; }; 93006D32B18174D9FE0A5E9E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatManager.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp; sourceTree = SOURCE_ROOT; };
41070806F82EC9C6D1C67689 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatManager.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.h; sourceTree = SOURCE_ROOT; }; 41070806F82EC9C6D1C67689 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatManager.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatManager.h; sourceTree = SOURCE_ROOT; };
9349E14552FEA0371553E808 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.cpp; sourceTree = SOURCE_ROOT; };
27356F5E93CEA4D472D83D8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatReader.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.h; sourceTree = SOURCE_ROOT; }; 27356F5E93CEA4D472D83D8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatReader.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatReader.h; sourceTree = SOURCE_ROOT; };
2AD64F53E12B20011B7A0DB7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFormatWriter.cpp; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.cpp; sourceTree = SOURCE_ROOT; };
8BD38C2507C0F8E28930A4F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatWriter.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.h; sourceTree = SOURCE_ROOT; }; 8BD38C2507C0F8E28930A4F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioFormatWriter.h; path = ../../src/audio/audio_file_formats/juce_AudioFormatWriter.h; sourceTree = SOURCE_ROOT; };
59597FA0A88A08937801D198 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioSubsectionReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp; sourceTree = SOURCE_ROOT; }; 59597FA0A88A08937801D198 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioSubsectionReader.cpp; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp; sourceTree = SOURCE_ROOT; };
AE7F7F0D959C2E3CF5989C88 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioSubsectionReader.h; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.h; sourceTree = SOURCE_ROOT; }; AE7F7F0D959C2E3CF5989C88 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AudioSubsectionReader.h; path = ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.h; sourceTree = SOURCE_ROOT; };
@@ -477,6 +482,8 @@
6C6C1C360138D9BD4B27588B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Sampler.h; path = ../../src/audio/synthesisers/juce_Sampler.h; sourceTree = SOURCE_ROOT; }; 6C6C1C360138D9BD4B27588B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Sampler.h; path = ../../src/audio/synthesisers/juce_Sampler.h; sourceTree = SOURCE_ROOT; };
35668D8EEA19957C6C9AC83A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Synthesiser.cpp; path = ../../src/audio/synthesisers/juce_Synthesiser.cpp; sourceTree = SOURCE_ROOT; }; 35668D8EEA19957C6C9AC83A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Synthesiser.cpp; path = ../../src/audio/synthesisers/juce_Synthesiser.cpp; sourceTree = SOURCE_ROOT; };
9E6C206F95245BCDE38FB2B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Synthesiser.h; path = ../../src/audio/synthesisers/juce_Synthesiser.h; sourceTree = SOURCE_ROOT; }; 9E6C206F95245BCDE38FB2B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Synthesiser.h; path = ../../src/audio/synthesisers/juce_Synthesiser.h; sourceTree = SOURCE_ROOT; };
4F22276689685D839BD252EA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AbstractFifo.cpp; path = ../../src/containers/juce_AbstractFifo.cpp; sourceTree = SOURCE_ROOT; };
9584B84F23A4251755D49213 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AbstractFifo.h; path = ../../src/containers/juce_AbstractFifo.h; sourceTree = SOURCE_ROOT; };
839BE8047CF2F8EBE43ED34F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Array.h; path = ../../src/containers/juce_Array.h; sourceTree = SOURCE_ROOT; }; 839BE8047CF2F8EBE43ED34F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Array.h; path = ../../src/containers/juce_Array.h; sourceTree = SOURCE_ROOT; };
EDF52FDF87ACD33FE933142C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrayAllocationBase.h; path = ../../src/containers/juce_ArrayAllocationBase.h; sourceTree = SOURCE_ROOT; }; EDF52FDF87ACD33FE933142C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrayAllocationBase.h; path = ../../src/containers/juce_ArrayAllocationBase.h; sourceTree = SOURCE_ROOT; };
895D742F49DA9F100990879C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_BigInteger.cpp; path = ../../src/containers/juce_BigInteger.cpp; sourceTree = SOURCE_ROOT; }; 895D742F49DA9F100990879C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_BigInteger.cpp; path = ../../src/containers/juce_BigInteger.cpp; sourceTree = SOURCE_ROOT; };
@@ -1048,7 +1055,9 @@
013E8938EE1C6B4F63016B55, 013E8938EE1C6B4F63016B55,
93006D32B18174D9FE0A5E9E, 93006D32B18174D9FE0A5E9E,
41070806F82EC9C6D1C67689, 41070806F82EC9C6D1C67689,
9349E14552FEA0371553E808,
27356F5E93CEA4D472D83D8E, 27356F5E93CEA4D472D83D8E,
2AD64F53E12B20011B7A0DB7,
8BD38C2507C0F8E28930A4F8, 8BD38C2507C0F8E28930A4F8,
59597FA0A88A08937801D198, 59597FA0A88A08937801D198,
AE7F7F0D959C2E3CF5989C88, AE7F7F0D959C2E3CF5989C88,
@@ -1195,6 +1204,8 @@
231431F8B23F01DC6ECD4214, 231431F8B23F01DC6ECD4214,
DC641C77950A335A20FD4532 ); name = audio; sourceTree = "<group>"; }; DC641C77950A335A20FD4532 ); name = audio; sourceTree = "<group>"; };
1CC2889DB696E12FC34E3F50 = { isa = PBXGroup; children = ( 1CC2889DB696E12FC34E3F50 = { isa = PBXGroup; children = (
4F22276689685D839BD252EA,
9584B84F23A4251755D49213,
839BE8047CF2F8EBE43ED34F, 839BE8047CF2F8EBE43ED34F,
EDF52FDF87ACD33FE933142C, EDF52FDF87ACD33FE933142C,
895D742F49DA9F100990879C, 895D742F49DA9F100990879C,
@@ -1915,6 +1926,8 @@
983FCD60625A60993546F850, 983FCD60625A60993546F850,
416D6F00E88DC74879B4DF2B, 416D6F00E88DC74879B4DF2B,
9C709BC2F4F0EE60BF52FACA, 9C709BC2F4F0EE60BF52FACA,
992F46189ABF711A047186A4,
5C312E6678456C8293633E0F,
FB21B7E6A7CE55D3C0E3C37E, FB21B7E6A7CE55D3C0E3C37E,
C1147D03F1F4D697CC30DD22, C1147D03F1F4D697CC30DD22,
C5CFF5508299C26380465290, C5CFF5508299C26380465290,
@@ -1961,6 +1974,7 @@
D1407BB28C169F5E1CAC3CC7, D1407BB28C169F5E1CAC3CC7,
07E6E11A658930554FF0C56A, 07E6E11A658930554FF0C56A,
E8DFABC1603D55B97429A8E4, E8DFABC1603D55B97429A8E4,
1F905F44E5FA23A2D5CCDA0A,
BE25871C34D79FEFFD1B94B6, BE25871C34D79FEFFD1B94B6,
4AB5E55BDF79028F82F83D8E, 4AB5E55BDF79028F82F83D8E,
25018C91F79D918FEA084630, 25018C91F79D918FEA084630,


+ 8
- 0
Juce.jucer View File

@@ -81,8 +81,12 @@
resource="0" file="src/audio/audio_file_formats/juce_AudioFormatManager.cpp"/> resource="0" file="src/audio/audio_file_formats/juce_AudioFormatManager.cpp"/>
<FILE id="cz5oBf3fx" name="juce_AudioFormatManager.h" compile="0" resource="0" <FILE id="cz5oBf3fx" name="juce_AudioFormatManager.h" compile="0" resource="0"
file="src/audio/audio_file_formats/juce_AudioFormatManager.h"/> file="src/audio/audio_file_formats/juce_AudioFormatManager.h"/>
<FILE id="0TiI3po" name="juce_AudioFormatReader.cpp" compile="1" resource="0"
file="src/audio/audio_file_formats/juce_AudioFormatReader.cpp"/>
<FILE id="x3bpEuQrJ" name="juce_AudioFormatReader.h" compile="0" resource="0" <FILE id="x3bpEuQrJ" name="juce_AudioFormatReader.h" compile="0" resource="0"
file="src/audio/audio_file_formats/juce_AudioFormatReader.h"/> file="src/audio/audio_file_formats/juce_AudioFormatReader.h"/>
<FILE id="G8yVpHF" name="juce_AudioFormatWriter.cpp" compile="1" resource="0"
file="src/audio/audio_file_formats/juce_AudioFormatWriter.cpp"/>
<FILE id="eCeRZdLR" name="juce_AudioFormatWriter.h" compile="0" resource="0" <FILE id="eCeRZdLR" name="juce_AudioFormatWriter.h" compile="0" resource="0"
file="src/audio/audio_file_formats/juce_AudioFormatWriter.h"/> file="src/audio/audio_file_formats/juce_AudioFormatWriter.h"/>
<FILE id="Fo4wJzEFh" name="juce_AudioSubsectionReader.cpp" compile="1" <FILE id="Fo4wJzEFh" name="juce_AudioSubsectionReader.cpp" compile="1"
@@ -346,6 +350,10 @@
</GROUP> </GROUP>
</GROUP> </GROUP>
<GROUP id="jDNvJtXHE" name="containers"> <GROUP id="jDNvJtXHE" name="containers">
<FILE id="ChnNms" name="juce_AbstractFifo.cpp" compile="1" resource="0"
file="src/containers/juce_AbstractFifo.cpp"/>
<FILE id="llcRKU5" name="juce_AbstractFifo.h" compile="0" resource="0"
file="src/containers/juce_AbstractFifo.h"/>
<FILE id="MMVvnl2oo" name="juce_Array.h" compile="0" resource="0" file="src/containers/juce_Array.h"/> <FILE id="MMVvnl2oo" name="juce_Array.h" compile="0" resource="0" file="src/containers/juce_Array.h"/>
<FILE id="I2LILZNlU" name="juce_ArrayAllocationBase.h" compile="0" <FILE id="I2LILZNlU" name="juce_ArrayAllocationBase.h" compile="0"
resource="0" file="src/containers/juce_ArrayAllocationBase.h"/> resource="0" file="src/containers/juce_ArrayAllocationBase.h"/>


+ 3
- 0
amalgamation/juce_amalgamated_template.cpp View File

@@ -103,6 +103,7 @@
#include "../src/core/juce_SystemStats.cpp" #include "../src/core/juce_SystemStats.cpp"
#include "../src/core/juce_Time.cpp" #include "../src/core/juce_Time.cpp"
#include "../src/core/juce_Initialisation.cpp" #include "../src/core/juce_Initialisation.cpp"
#include "../src/containers/juce_AbstractFifo.cpp"
#include "../src/containers/juce_BigInteger.cpp" #include "../src/containers/juce_BigInteger.cpp"
#include "../src/containers/juce_MemoryBlock.cpp" #include "../src/containers/juce_MemoryBlock.cpp"
#include "../src/containers/juce_PropertySet.cpp" #include "../src/containers/juce_PropertySet.cpp"
@@ -164,6 +165,8 @@
#include "../src/utilities/juce_UndoManager.cpp" #include "../src/utilities/juce_UndoManager.cpp"
#include "../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp" #include "../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp"
#include "../src/audio/audio_file_formats/juce_AudioFormat.cpp" #include "../src/audio/audio_file_formats/juce_AudioFormat.cpp"
#include "../src/audio/audio_file_formats/juce_AudioFormatReader.cpp"
#include "../src/audio/audio_file_formats/juce_AudioFormatWriter.cpp"
#include "../src/audio/audio_file_formats/juce_AudioFormatManager.cpp" #include "../src/audio/audio_file_formats/juce_AudioFormatManager.cpp"
#include "../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp" #include "../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp"
#include "../src/audio/audio_file_formats/juce_AudioThumbnail.cpp" #include "../src/audio/audio_file_formats/juce_AudioThumbnail.cpp"


+ 1
- 1
extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h View File

@@ -505,7 +505,7 @@ private:
s.add ("ZERO_LINK = NO"); s.add ("ZERO_LINK = NO");
if (! isRTAS()) // (dwarf seems to be incompatible with the RTAS libs) if (! isRTAS()) // (dwarf seems to be incompatible with the RTAS libs)
s.add ("DEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\"");
s.add ("DEBUG_INFORMATION_FORMAT = \"dwarf\"");
s.add ("PRODUCT_NAME = \"" + config.getTargetBinaryName().toString() + "\""); s.add ("PRODUCT_NAME = \"" + config.getTargetBinaryName().toString() + "\"");
return s; return s;


+ 49
- 150
extras/juce demo/Source/demos/AudioDemoRecordPage.cpp View File

@@ -27,112 +27,19 @@
//[MiscUserDefs] You can add your own user definitions and misc code here... //[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
/** A simple class that acts as an AudioIODeviceCallback and writes the
incoming audio data to a WAV file.
*/
class AudioRecorder : public AudioIODeviceCallback
{ {
public: public:
AudioRecorder() AudioRecorder()
: Thread ("audio recorder"),
circularBuffer (2, 48000),
recording (false),
sampleRate (0)
: backgroundThread ("Audio Recorder Thread"),
sampleRate (0), activeWriter (0)
{ {
backgroundThread.startThread();
} }
~AudioRecorder() ~AudioRecorder()
@@ -147,24 +54,49 @@ public:
if (sampleRate > 0) if (sampleRate > 0)
{ {
fileToRecord = file;
startThread();
// Create an OutputStream to write to our destination file...
file.deleteFile();
ScopedPointer<FileOutputStream> fileStream (file.createOutputStream());
circularBuffer.clear();
recording = true;
if (fileStream != 0)
{
// Now create a WAV writer object that writes to our output stream...
WavAudioFormat wavFormat;
AudioFormatWriter* writer = wavFormat.createWriterFor (fileStream, sampleRate, 1, 16, StringPairArray(), 0);
if (writer != 0)
{
fileStream.release(); // (passes responsibility for deleting the stream to the writer object that is now using it)
// Now we'll create one of these helper objects which will act as a FIFO buffer, and will
// write the data to disk on our background thread.
threadedWriter = new AudioFormatWriter::ThreadedWriter (writer, backgroundThread, 32768);
// And now, swap over our active writer pointer so that the audio callback will start using it..
const ScopedLock sl (writerLock);
activeWriter = threadedWriter;
}
}
} }
} }
void stop() void stop()
{ {
recording = false;
// First, clear this pointer to stop the audio callback from using our writer object..
{
const ScopedLock sl (writerLock);
activeWriter = 0;
}
stopThread (5000);
// Now we can delete the writer object. It's done in this order because the deletion could
// take a little time while remaining data gets flushed to disk, so it's best to avoid blocking
// the audio callback while this happens.
threadedWriter = 0;
} }
bool isRecording() const bool isRecording() const
{ {
return isThreadRunning() && recording;
return activeWriter != 0;
} }
//============================================================================== //==============================================================================
@@ -182,11 +114,10 @@ public:
float** outputChannelData, int numOutputChannels, float** outputChannelData, int numOutputChannels,
int numSamples) int numSamples)
{ {
if (recording)
{
const AudioSampleBuffer incomingData ((float**) inputChannelData, numInputChannels, numSamples);
circularBuffer.addSamplesToBuffer (incomingData, numSamples);
}
const ScopedLock sl (writerLock);
if (activeWriter != 0)
activeWriter->write (inputChannelData, numSamples);
// We need to clear the output buffers, in case they're full of junk.. // We need to clear the output buffers, in case they're full of junk..
for (int i = 0; i < numOutputChannels; ++i) for (int i = 0; i < numOutputChannels; ++i)
@@ -194,44 +125,13 @@ public:
zeromem (outputChannelData[i], sizeof (float) * numSamples); 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;
private:
TimeSliceThread backgroundThread; // the thread that will write our audio data to disk
ScopedPointer<AudioFormatWriter::ThreadedWriter> threadedWriter; // the FIFO used to buffer the incoming data
double sampleRate; double sampleRate;
bool recording;
CircularAudioBuffer circularBuffer;
CriticalSection writerLock;
AudioFormatWriter::ThreadedWriter* volatile activeWriter;
}; };
//[/MiscUserDefs] //[/MiscUserDefs]
@@ -275,10 +175,9 @@ AudioDemoRecordPage::AudioDemoRecordPage (AudioDeviceManager& deviceManager_)
AudioDemoRecordPage::~AudioDemoRecordPage() AudioDemoRecordPage::~AudioDemoRecordPage()
{ {
//[Destructor_pre]. You can add your own custom destruction code here.. //[Destructor_pre]. You can add your own custom destruction code here..
recorder->stop();
deviceManager.removeAudioCallback (recorder); deviceManager.removeAudioCallback (recorder);
delete recorder;
deviceManager.removeAudioCallback (liveAudioDisplayComp); deviceManager.removeAudioCallback (liveAudioDisplayComp);
recorder = 0;
//[/Destructor_pre] //[/Destructor_pre]
deleteAndZero (liveAudioDisplayComp); deleteAndZero (liveAudioDisplayComp);


+ 1
- 1
extras/juce demo/Source/demos/AudioDemoRecordPage.h View File

@@ -62,7 +62,7 @@ public:
private: private:
//[UserVariables] -- You can add your own custom variables in this section. //[UserVariables] -- You can add your own custom variables in this section.
AudioDeviceManager& deviceManager; AudioDeviceManager& deviceManager;
AudioRecorder* recorder;
ScopedPointer<AudioRecorder> recorder;
//[/UserVariables] //[/UserVariables]
//============================================================================== //==============================================================================


+ 270
- 157
juce_amalgamated.cpp View File

@@ -2407,6 +2407,100 @@ END_JUCE_NAMESPACE
/*** End of inlined file: juce_Initialisation.cpp ***/ /*** End of inlined file: juce_Initialisation.cpp ***/




/*** Start of inlined file: juce_AbstractFifo.cpp ***/
BEGIN_JUCE_NAMESPACE

AbstractFifo::AbstractFifo (const int capacity) throw()
: bufferSize (capacity)
{
jassert (bufferSize > 0);
}

AbstractFifo::~AbstractFifo() {}

int AbstractFifo::getTotalSize() const throw() { return bufferSize; }
int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); }
int AbstractFifo::getNumReady() const throw() { return validEnd.get() - validStart.get(); }

void AbstractFifo::reset() throw()
{
validEnd = 0;
validStart = 0;
}

void AbstractFifo::setTotalSize (int newSize) throw()
{
jassert (newSize > 0);
reset();
bufferSize = newSize;
}

void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw()
{
const int vs = validStart.get();
const int ve = validEnd.get();

const int freeSpace = bufferSize - (ve - vs);
numToWrite = jmin (numToWrite, freeSpace);

if (numToWrite <= 0)
{
startIndex1 = 0;
startIndex2 = 0;
blockSize1 = 0;
blockSize2 = 0;
}
else
{
startIndex1 = (int) (ve % bufferSize);
startIndex2 = 0;
blockSize1 = jmin (bufferSize - startIndex1, numToWrite);
numToWrite -= blockSize1;
blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, (int) (vs % bufferSize));
}
}

void AbstractFifo::finishedWrite (int numWritten) throw()
{
jassert (numWritten >= 0 && numWritten < bufferSize);
validEnd += numWritten;
}

void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw()
{
const int vs = validStart.get();
const int ve = validEnd.get();

const int numReady = ve - vs;
numWanted = jmin (numWanted, numReady);

if (numWanted <= 0)
{
startIndex1 = 0;
startIndex2 = 0;
blockSize1 = 0;
blockSize2 = 0;
}
else
{
startIndex1 = (int) (vs % bufferSize);
startIndex2 = 0;
blockSize1 = jmin (bufferSize - startIndex1, numWanted);
numWanted -= blockSize1;
blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, (int) (ve % bufferSize));
}
}

void AbstractFifo::finishedRead (int numRead) throw()
{
jassert (numRead >= 0 && numRead < bufferSize);
validStart += numRead;
}

END_JUCE_NAMESPACE
/*** End of inlined file: juce_AbstractFifo.cpp ***/


/*** Start of inlined file: juce_BigInteger.cpp ***/ /*** Start of inlined file: juce_BigInteger.cpp ***/
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE


@@ -20755,7 +20849,7 @@ public:
{ {
switch (bitsPerSample) switch (bitsPerSample)
{ {
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
@@ -20766,7 +20860,7 @@ public:
{ {
switch (bitsPerSample) switch (bitsPerSample)
{ {
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
@@ -21007,6 +21101,37 @@ END_JUCE_NAMESPACE
/*** Start of inlined file: juce_AudioFormat.cpp ***/ /*** Start of inlined file: juce_AudioFormat.cpp ***/
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE


AudioFormat::AudioFormat (const String& name, const StringArray& extensions)
: formatName (name),
fileExtensions (extensions)
{
}

AudioFormat::~AudioFormat()
{
}

bool AudioFormat::canHandleFile (const File& f)
{
for (int i = 0; i < fileExtensions.size(); ++i)
if (f.hasFileExtension (fileExtensions[i]))
return true;

return false;
}

const String& AudioFormat::getFormatName() const { return formatName; }
const StringArray& AudioFormat::getFileExtensions() const { return fileExtensions; }
bool AudioFormat::isCompressed() { return false; }
const StringArray AudioFormat::getQualityOptions() { return StringArray(); }

END_JUCE_NAMESPACE
/*** End of inlined file: juce_AudioFormat.cpp ***/


/*** Start of inlined file: juce_AudioFormatReader.cpp ***/
BEGIN_JUCE_NAMESPACE

AudioFormatReader::AudioFormatReader (InputStream* const in, AudioFormatReader::AudioFormatReader (InputStream* const in,
const String& formatName_) const String& formatName_)
: sampleRate (0), : sampleRate (0),
@@ -21338,6 +21463,13 @@ int64 AudioFormatReader::searchForLevel (int64 startSample,
return -1; return -1;
} }


END_JUCE_NAMESPACE
/*** End of inlined file: juce_AudioFormatReader.cpp ***/


/*** Start of inlined file: juce_AudioFormatWriter.cpp ***/
BEGIN_JUCE_NAMESPACE

AudioFormatWriter::AudioFormatWriter (OutputStream* const out, AudioFormatWriter::AudioFormatWriter (OutputStream* const out,
const String& formatName_, const String& formatName_,
const double rate, const double rate,
@@ -21424,16 +21556,9 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
return true; return true;
} }


bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,
int numSamplesToRead,
const int samplesPerBlock)
bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, int numSamplesToRead, const int samplesPerBlock)
{ {
AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock); AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock);
int* buffers [128];
zerostruct (buffers);

for (int i = tempBuffer.getNumChannels(); --i >= 0;)
buffers[i] = reinterpret_cast<int*> (tempBuffer.getSampleData (i, 0));


while (numSamplesToRead > 0) while (numSamplesToRead > 0)
{ {
@@ -21447,30 +21572,7 @@ bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,


source.getNextAudioBlock (info); source.getNextAudioBlock (info);


if (! isFloatingPoint())
{
int** bufferChan = buffers;

while (*bufferChan != 0)
{
int* b = *bufferChan++;

// float -> int
for (int j = numToDo; --j >= 0;)
{
const double samp = *(const float*) b;

if (samp <= -1.0)
*b++ = std::numeric_limits<int>::min();
else if (samp >= 1.0)
*b++ = std::numeric_limits<int>::max();
else
*b++ = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}

if (! write ((const int**) buffers, numToDo))
if (! writeFromAudioSampleBuffer (tempBuffer, 0, numToDo))
return false; return false;


numSamplesToRead -= numToDo; numSamplesToRead -= numToDo;
@@ -21479,48 +21581,131 @@ bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,
return true; return true;
} }


AudioFormat::AudioFormat (const String& name,
const StringArray& extensions)
: formatName (name),
fileExtensions (extensions)
bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples)
{ {
}
jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && source.getNumChannels() > 0);


AudioFormat::~AudioFormat()
{
}
if (numSamples <= 0)
return true;


const String& AudioFormat::getFormatName() const
{
return formatName;
}
HeapBlock<int> tempBuffer;
HeapBlock<int*> chans (numChannels + 1);
chans [numChannels] = 0;


const StringArray& AudioFormat::getFileExtensions() const
{
return fileExtensions;
if (isFloatingPoint())
{
for (int i = numChannels; --i >= 0;)
chans[i] = reinterpret_cast<int*> (source.getSampleData (i, startSample));
}
else
{
tempBuffer.malloc (numSamples * numChannels);

for (unsigned int i = 0; i < numChannels; ++i)
{
typedef AudioData::Pointer <AudioData::Int32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestSampleType;
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceSampleType;

DestSampleType destData (chans[i] = tempBuffer + i * numSamples);
SourceSampleType sourceData (source.getSampleData (i, startSample));
destData.convertSamples (sourceData, numSamples);
}
}

return write ((const int**) chans.getData(), numSamples);
} }


bool AudioFormat::canHandleFile (const File& f)
class AudioFormatWriter::ThreadedWriter::Buffer : public TimeSliceClient,
public AbstractFifo
{ {
for (int i = 0; i < fileExtensions.size(); ++i)
if (f.hasFileExtension (fileExtensions[i]))
public:
Buffer (TimeSliceThread& timeSliceThread_, AudioFormatWriter* writer_, int numChannels, int bufferSize)
: AbstractFifo (bufferSize),
buffer (numChannels, bufferSize),
timeSliceThread (timeSliceThread_),
writer (writer_), isRunning (true)
{
timeSliceThread.addTimeSliceClient (this);
}

~Buffer()
{
isRunning = false;
timeSliceThread.removeTimeSliceClient (this);

while (useTimeSlice())
{}
}

bool write (const float** data, int numSamples)
{
if (numSamples <= 0 || ! isRunning)
return true; return true;


return false;
jassert (timeSliceThread.isThreadRunning()); // you need to get your thread running before pumping data into this!

int start1, size1, start2, size2;
prepareToWrite (numSamples, start1, size1, start2, size2);

if (size1 + size2 < numSamples)
return false;

for (int i = buffer.getNumChannels(); --i >= 0;)
{
buffer.copyFrom (i, start1, data[i], size1);
buffer.copyFrom (i, start2, data[i] + size1, size2);
}

finishedWrite (size1 + size2);
timeSliceThread.notify();
return true;
}

bool useTimeSlice()
{
const int numToDo = getTotalSize() / 4;

int start1, size1, start2, size2;
prepareToRead (numToDo, start1, size1, start2, size2);

if (size1 <= 0)
return false;

writer->writeFromAudioSampleBuffer (buffer, start1, size1);

if (size2 > 0)
writer->writeFromAudioSampleBuffer (buffer, start2, size2);

finishedRead (size1 + size2);
return true;
}

private:
AudioSampleBuffer buffer;
TimeSliceThread& timeSliceThread;
ScopedPointer<AudioFormatWriter> writer;
volatile bool isRunning;

Buffer (const Buffer&);
Buffer& operator= (const Buffer&);
};

AudioFormatWriter::ThreadedWriter::ThreadedWriter (AudioFormatWriter* writer, TimeSliceThread& backgroundThread, int numSamplesToBuffer)
: buffer (new AudioFormatWriter::ThreadedWriter::Buffer (backgroundThread, writer, writer->numChannels, numSamplesToBuffer))
{
} }


bool AudioFormat::isCompressed()
AudioFormatWriter::ThreadedWriter::~ThreadedWriter()
{ {
return false;
} }


const StringArray AudioFormat::getQualityOptions()
bool AudioFormatWriter::ThreadedWriter::write (const float** data, int numSamples)
{ {
return StringArray();
return buffer->write (data, numSamples);
} }


END_JUCE_NAMESPACE END_JUCE_NAMESPACE
/*** End of inlined file: juce_AudioFormat.cpp ***/
/*** End of inlined file: juce_AudioFormatWriter.cpp ***/




/*** Start of inlined file: juce_AudioFormatManager.cpp ***/ /*** Start of inlined file: juce_AudioFormatManager.cpp ***/
@@ -22668,25 +22853,11 @@ QuickTimeAudioFormat::~QuickTimeAudioFormat()
{ {
} }


const Array <int> QuickTimeAudioFormat::getPossibleSampleRates()
{
return Array<int>();
}

const Array <int> QuickTimeAudioFormat::getPossibleBitDepths()
{
return Array<int>();
}
const Array <int> QuickTimeAudioFormat::getPossibleSampleRates() { return Array<int>(); }
const Array <int> QuickTimeAudioFormat::getPossibleBitDepths() { return Array<int>(); }


bool QuickTimeAudioFormat::canDoStereo()
{
return true;
}

bool QuickTimeAudioFormat::canDoMono()
{
return true;
}
bool QuickTimeAudioFormat::canDoStereo() { return true; }
bool QuickTimeAudioFormat::canDoMono() { return true; }


AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream, AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream,
const bool deleteStreamIfOpeningFails) const bool deleteStreamIfOpeningFails)
@@ -27314,45 +27485,8 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer,
const int startSample, const int startSample,
const int numSamples) const const int numSamples) const
{ {
jassert (startSample >= 0 && startSample + numSamples <= size && numChannels > 0);

if (numSamples > 0)
{
HeapBlock<int> tempBuffer;
HeapBlock<int*> chans (numChannels + 1);
chans [numChannels] = 0;

if (writer->isFloatingPoint())
{
for (int i = numChannels; --i >= 0;)
chans[i] = reinterpret_cast<int*> (channels[i] + startSample);
}
else
{
tempBuffer.malloc (numSamples * numChannels);

for (int j = 0; j < numChannels; ++j)
{
int* const dest = tempBuffer + j * numSamples;
const float* const src = channels[j] + startSample;
chans[j] = dest;

for (int i = 0; i < numSamples; ++i)
{
const double samp = src[i];

if (samp <= -1.0)
dest[i] = std::numeric_limits<int>::min();
else if (samp >= 1.0)
dest[i] = std::numeric_limits<int>::max();
else
dest[i] = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}

writer->write ((const int**) chans.getData(), numSamples);
}
jassert (writer != 0);
writer->writeFromAudioSampleBuffer (*this, startSample, numSamples);
} }


END_JUCE_NAMESPACE END_JUCE_NAMESPACE
@@ -69046,8 +69180,6 @@ public:
menuCreationTime = lastFocused = lastScroll = Time::getMillisecondCounter(); menuCreationTime = lastFocused = lastScroll = Time::getMillisecondCounter();
setWantsKeyboardFocus (true); setWantsKeyboardFocus (true);
setMouseClickGrabsKeyboardFocus (false); setMouseClickGrabsKeyboardFocus (false);

setOpaque (true);
setAlwaysOnTop (true); setAlwaysOnTop (true);


Desktop::getInstance().addGlobalMouseListener (this); Desktop::getInstance().addGlobalMouseListener (this);
@@ -69086,6 +69218,7 @@ public:
ScopedPointer <Window> mw (new Window()); ScopedPointer <Window> mw (new Window());
mw->setLookAndFeel (menu.lookAndFeel); mw->setLookAndFeel (menu.lookAndFeel);
mw->setWantsKeyboardFocus (false); mw->setWantsKeyboardFocus (false);
mw->setOpaque (mw->getLookAndFeel().findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows());
mw->minimumWidth = minimumWidth; mw->minimumWidth = minimumWidth;
mw->maximumNumColumns = maximumNumColumns; mw->maximumNumColumns = maximumNumColumns;
mw->standardItemHeight = standardItemHeight; mw->standardItemHeight = standardItemHeight;
@@ -69131,6 +69264,9 @@ public:


void paint (Graphics& g) void paint (Graphics& g)
{ {
if (isOpaque())
g.fillAll (Colours::white);

getLookAndFeel().drawPopupMenuBackground (g, getWidth(), getHeight()); getLookAndFeel().drawPopupMenuBackground (g, getWidth(), getHeight());
} }


@@ -128589,18 +128725,17 @@ class FlacWriter : public AudioFormatWriter
{ {
public: public:


FlacWriter (OutputStream* const out,
const double sampleRate_,
const int numChannels_,
const int bitsPerSample_)
FlacWriter (OutputStream* const out, double sampleRate_,
int numChannels_, int bitsPerSample_, int qualityOptionIndex)
: AudioFormatWriter (out, TRANS (flacFormatName), : AudioFormatWriter (out, TRANS (flacFormatName),
sampleRate_,
numChannels_,
bitsPerSample_)
sampleRate_, numChannels_, bitsPerSample_)
{ {
using namespace FlacNamespace; using namespace FlacNamespace;
encoder = FLAC__stream_encoder_new(); encoder = FLAC__stream_encoder_new();


if (qualityOptionIndex > 0)
FLAC__stream_encoder_set_compression_level (encoder, jmin (8, qualityOptionIndex));

FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2); FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2);
FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2); FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2);
FLAC__stream_encoder_set_channels (encoder, numChannels); FLAC__stream_encoder_set_channels (encoder, numChannels);
@@ -128780,20 +128915,9 @@ const Array <int> FlacAudioFormat::getPossibleBitDepths()
return Array <int> (depths); return Array <int> (depths);
} }


bool FlacAudioFormat::canDoStereo()
{
return true;
}

bool FlacAudioFormat::canDoMono()
{
return true;
}

bool FlacAudioFormat::isCompressed()
{
return true;
}
bool FlacAudioFormat::canDoStereo() { return true; }
bool FlacAudioFormat::canDoMono() { return true; }
bool FlacAudioFormat::isCompressed() { return true; }


AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in, AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in,
const bool deleteStreamIfOpeningFails) const bool deleteStreamIfOpeningFails)
@@ -128814,11 +128938,11 @@ AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
unsigned int numberOfChannels, unsigned int numberOfChannels,
int bitsPerSample, int bitsPerSample,
const StringPairArray& /*metadataValues*/, const StringPairArray& /*metadataValues*/,
int /*qualityOptionIndex*/)
int qualityOptionIndex)
{ {
if (getPossibleBitDepths().contains (bitsPerSample)) if (getPossibleBitDepths().contains (bitsPerSample))
{ {
ScopedPointer<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels, bitsPerSample));
ScopedPointer<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels, bitsPerSample, qualityOptionIndex));


if (w->ok) if (w->ok)
return w.release(); return w.release();
@@ -187791,20 +187915,13 @@ const Array <int> OggVorbisAudioFormat::getPossibleSampleRates()


const Array <int> OggVorbisAudioFormat::getPossibleBitDepths() const Array <int> OggVorbisAudioFormat::getPossibleBitDepths()
{ {
Array <int> depths;
depths.add (32);
return depths;
const int depths[] = { 32, 0 };
return Array <int> (depths);
} }


bool OggVorbisAudioFormat::canDoStereo()
{
return true;
}

bool OggVorbisAudioFormat::canDoMono()
{
return true;
}
bool OggVorbisAudioFormat::canDoStereo() { return true; }
bool OggVorbisAudioFormat::canDoMono() { return true; }
bool OggVorbisAudioFormat::isCompressed() { return true; }


AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in, AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in,
const bool deleteStreamIfOpeningFails) const bool deleteStreamIfOpeningFails)
@@ -187836,11 +187953,6 @@ AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out,
return w->ok ? w.release() : 0; return w->ok ? w.release() : 0;
} }


bool OggVorbisAudioFormat::isCompressed()
{
return true;
}

const StringArray OggVorbisAudioFormat::getQualityOptions() const StringArray OggVorbisAudioFormat::getQualityOptions()
{ {
StringArray s; StringArray s;
@@ -242900,6 +243012,7 @@ private:
return 0; return 0;


case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGED:
doMouseEvent (getCurrentMousePos());
handleMovedOrResized(); handleMovedOrResized();


if (dontRepaint) if (dontRepaint)


+ 655
- 409
juce_amalgamated.h
File diff suppressed because it is too large
View File


+ 2
- 2
src/audio/audio_file_formats/juce_AiffAudioFormat.cpp View File

@@ -188,7 +188,7 @@ public:
{ {
switch (bitsPerSample) switch (bitsPerSample)
{ {
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
@@ -199,7 +199,7 @@ public:
{ {
switch (bitsPerSample) switch (bitsPerSample)
{ {
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 8: ReadHelper<AudioData::Int32, AudioData::Int8, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;
case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break; case 32: ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::BigEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, tempBuffer, numChannels, numThisTime); break;


+ 5
- 496
src/audio/audio_file_formats/juce_AudioFormat.cpp View File

@@ -28,486 +28,10 @@
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE
#include "juce_AudioFormat.h" #include "juce_AudioFormat.h"
#include "../dsp/juce_AudioSampleBuffer.h"
//============================================================================== //==============================================================================
AudioFormatReader::AudioFormatReader (InputStream* const in,
const String& formatName_)
: sampleRate (0),
bitsPerSample (0),
lengthInSamples (0),
numChannels (0),
usesFloatingPointData (false),
input (in),
formatName (formatName_)
{
}
AudioFormatReader::~AudioFormatReader()
{
delete input;
}
bool AudioFormatReader::read (int* const* destSamples,
int numDestChannels,
int64 startSampleInSource,
int numSamplesToRead,
const bool fillLeftoverChannelsWithCopies)
{
jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
int startOffsetInDestBuffer = 0;
if (startSampleInSource < 0)
{
const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
for (int i = numDestChannels; --i >= 0;)
if (destSamples[i] != 0)
zeromem (destSamples[i], sizeof (int) * silence);
startOffsetInDestBuffer += silence;
numSamplesToRead -= silence;
startSampleInSource = 0;
}
if (numSamplesToRead <= 0)
return true;
if (! readSamples (const_cast<int**> (destSamples),
jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
startSampleInSource, numSamplesToRead))
return false;
if (numDestChannels > (int) numChannels)
{
if (fillLeftoverChannelsWithCopies)
{
int* lastFullChannel = destSamples[0];
for (int i = (int) numChannels; --i > 0;)
{
if (destSamples[i] != 0)
{
lastFullChannel = destSamples[i];
break;
}
}
if (lastFullChannel != 0)
for (int i = numChannels; i < numDestChannels; ++i)
if (destSamples[i] != 0)
memcpy (destSamples[i], lastFullChannel, sizeof (int) * numSamplesToRead);
}
else
{
for (int i = numChannels; i < numDestChannels; ++i)
if (destSamples[i] != 0)
zeromem (destSamples[i], sizeof (int) * numSamplesToRead);
}
}
return true;
}
static void findAudioBufferMaxMin (const float* const buffer, const int num, float& maxVal, float& minVal) throw()
{
float mn = buffer[0];
float mx = mn;
for (int i = 1; i < num; ++i)
{
const float s = buffer[i];
if (s > mx) mx = s;
if (s < mn) mn = s;
}
maxVal = mx;
minVal = mn;
}
void AudioFormatReader::readMaxLevels (int64 startSampleInFile,
int64 numSamples,
float& lowestLeft, float& highestLeft,
float& lowestRight, float& highestRight)
{
if (numSamples <= 0)
{
lowestLeft = 0;
lowestRight = 0;
highestLeft = 0;
highestRight = 0;
return;
}
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
HeapBlock<int> tempSpace (bufferSize * 2 + 64);
int* tempBuffer[3];
tempBuffer[0] = tempSpace.getData();
tempBuffer[1] = tempSpace.getData() + bufferSize;
tempBuffer[2] = 0;
if (usesFloatingPointData)
{
float lmin = 1.0e6f;
float lmax = -lmin;
float rmin = lmin;
float rmax = lmax;
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
read (tempBuffer, 2, startSampleInFile, numToDo, false);
numSamples -= numToDo;
startSampleInFile += numToDo;
float bufmin, bufmax;
findAudioBufferMaxMin (reinterpret_cast<float*> (tempBuffer[0]), numToDo, bufmax, bufmin);
lmin = jmin (lmin, bufmin);
lmax = jmax (lmax, bufmax);
if (numChannels > 1)
{
findAudioBufferMaxMin (reinterpret_cast<float*> (tempBuffer[1]), numToDo, bufmax, bufmin);
rmin = jmin (rmin, bufmin);
rmax = jmax (rmax, bufmax);
}
}
if (numChannels <= 1)
{
rmax = lmax;
rmin = lmin;
}
lowestLeft = lmin;
highestLeft = lmax;
lowestRight = rmin;
highestRight = rmax;
}
else
{
int lmax = std::numeric_limits<int>::min();
int lmin = std::numeric_limits<int>::max();
int rmax = std::numeric_limits<int>::min();
int rmin = std::numeric_limits<int>::max();
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
read (tempBuffer, 2, startSampleInFile, numToDo, false);
numSamples -= numToDo;
startSampleInFile += numToDo;
for (int j = numChannels; --j >= 0;)
{
int bufMax = std::numeric_limits<int>::min();
int bufMin = std::numeric_limits<int>::max();
const int* const b = tempBuffer[j];
for (int i = 0; i < numToDo; ++i)
{
const int samp = b[i];
if (samp < bufMin)
bufMin = samp;
if (samp > bufMax)
bufMax = samp;
}
if (j == 0)
{
lmax = jmax (lmax, bufMax);
lmin = jmin (lmin, bufMin);
}
else
{
rmax = jmax (rmax, bufMax);
rmin = jmin (rmin, bufMin);
}
}
}
if (numChannels <= 1)
{
rmax = lmax;
rmin = lmin;
}
lowestLeft = lmin / (float) std::numeric_limits<int>::max();
highestLeft = lmax / (float) std::numeric_limits<int>::max();
lowestRight = rmin / (float) std::numeric_limits<int>::max();
highestRight = rmax / (float) std::numeric_limits<int>::max();
}
}
int64 AudioFormatReader::searchForLevel (int64 startSample,
int64 numSamplesToSearch,
const double magnitudeRangeMinimum,
const double magnitudeRangeMaximum,
const int minimumConsecutiveSamples)
{
if (numSamplesToSearch == 0)
return -1;
const int bufferSize = 4096;
HeapBlock<int> tempSpace (bufferSize * 2 + 64);
int* tempBuffer[3];
tempBuffer[0] = tempSpace.getData();
tempBuffer[1] = tempSpace.getData() + bufferSize;
tempBuffer[2] = 0;
int consecutive = 0;
int64 firstMatchPos = -1;
jassert (magnitudeRangeMaximum > magnitudeRangeMinimum);
const double doubleMin = jlimit (0.0, (double) std::numeric_limits<int>::max(), magnitudeRangeMinimum * std::numeric_limits<int>::max());
const double doubleMax = jlimit (doubleMin, (double) std::numeric_limits<int>::max(), magnitudeRangeMaximum * std::numeric_limits<int>::max());
const int intMagnitudeRangeMinimum = roundToInt (doubleMin);
const int intMagnitudeRangeMaximum = roundToInt (doubleMax);
while (numSamplesToSearch != 0)
{
const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize);
int64 bufferStart = startSample;
if (numSamplesToSearch < 0)
bufferStart -= numThisTime;
if (bufferStart >= (int) lengthInSamples)
break;
read (tempBuffer, 2, bufferStart, numThisTime, false);
int num = numThisTime;
while (--num >= 0)
{
if (numSamplesToSearch < 0)
--startSample;
bool matches = false;
const int index = (int) (startSample - bufferStart);
if (usesFloatingPointData)
{
const float sample1 = std::abs (((float*) tempBuffer[0]) [index]);
if (sample1 >= magnitudeRangeMinimum
&& sample1 <= magnitudeRangeMaximum)
{
matches = true;
}
else if (numChannels > 1)
{
const float sample2 = std::abs (((float*) tempBuffer[1]) [index]);
matches = (sample2 >= magnitudeRangeMinimum
&& sample2 <= magnitudeRangeMaximum);
}
}
else
{
const int sample1 = abs (tempBuffer[0] [index]);
if (sample1 >= intMagnitudeRangeMinimum
&& sample1 <= intMagnitudeRangeMaximum)
{
matches = true;
}
else if (numChannels > 1)
{
const int sample2 = abs (tempBuffer[1][index]);
matches = (sample2 >= intMagnitudeRangeMinimum
&& sample2 <= intMagnitudeRangeMaximum);
}
}
if (matches)
{
if (firstMatchPos < 0)
firstMatchPos = startSample;
if (++consecutive >= minimumConsecutiveSamples)
{
if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples)
return -1;
return firstMatchPos;
}
}
else
{
consecutive = 0;
firstMatchPos = -1;
}
if (numSamplesToSearch > 0)
++startSample;
}
if (numSamplesToSearch > 0)
numSamplesToSearch -= numThisTime;
else
numSamplesToSearch += numThisTime;
}
return -1;
}
//==============================================================================
AudioFormatWriter::AudioFormatWriter (OutputStream* const out,
const String& formatName_,
const double rate,
const unsigned int numChannels_,
const unsigned int bitsPerSample_)
: sampleRate (rate),
numChannels (numChannels_),
bitsPerSample (bitsPerSample_),
usesFloatingPointData (false),
output (out),
formatName (formatName_)
{
}
AudioFormatWriter::~AudioFormatWriter()
{
delete output;
}
bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
int64 startSample,
int64 numSamplesToRead)
{
const int bufferSize = 16384;
AudioSampleBuffer tempBuffer (numChannels, bufferSize);
int* buffers [128];
zerostruct (buffers);
for (int i = tempBuffer.getNumChannels(); --i >= 0;)
buffers[i] = reinterpret_cast<int*> (tempBuffer.getSampleData (i, 0));
if (numSamplesToRead < 0)
numSamplesToRead = reader.lengthInSamples;
while (numSamplesToRead > 0)
{
const int numToDo = (int) jmin (numSamplesToRead, (int64) bufferSize);
if (! reader.read (buffers, numChannels, startSample, numToDo, false))
return false;
if (reader.usesFloatingPointData != isFloatingPoint())
{
int** bufferChan = buffers;
while (*bufferChan != 0)
{
int* b = *bufferChan++;
if (isFloatingPoint())
{
// int -> float
const double factor = 1.0 / std::numeric_limits<int>::max();
for (int i = 0; i < numToDo; ++i)
((float*) b)[i] = (float) (factor * b[i]);
}
else
{
// float -> int
for (int i = 0; i < numToDo; ++i)
{
const double samp = *(const float*) b;
if (samp <= -1.0)
*b++ = std::numeric_limits<int>::min();
else if (samp >= 1.0)
*b++ = std::numeric_limits<int>::max();
else
*b++ = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}
}
if (! write (const_cast<const int**> (buffers), numToDo))
return false;
numSamplesToRead -= numToDo;
startSample += numToDo;
}
return true;
}
bool AudioFormatWriter::writeFromAudioSource (AudioSource& source,
int numSamplesToRead,
const int samplesPerBlock)
{
AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock);
int* buffers [128];
zerostruct (buffers);
for (int i = tempBuffer.getNumChannels(); --i >= 0;)
buffers[i] = reinterpret_cast<int*> (tempBuffer.getSampleData (i, 0));
while (numSamplesToRead > 0)
{
const int numToDo = jmin (numSamplesToRead, samplesPerBlock);
AudioSourceChannelInfo info;
info.buffer = &tempBuffer;
info.startSample = 0;
info.numSamples = numToDo;
info.clearActiveBufferRegion();
source.getNextAudioBlock (info);
if (! isFloatingPoint())
{
int** bufferChan = buffers;
while (*bufferChan != 0)
{
int* b = *bufferChan++;
// float -> int
for (int j = numToDo; --j >= 0;)
{
const double samp = *(const float*) b;
if (samp <= -1.0)
*b++ = std::numeric_limits<int>::min();
else if (samp >= 1.0)
*b++ = std::numeric_limits<int>::max();
else
*b++ = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}
if (! write ((const int**) buffers, numToDo))
return false;
numSamplesToRead -= numToDo;
}
return true;
}
//==============================================================================
AudioFormat::AudioFormat (const String& name,
const StringArray& extensions)
AudioFormat::AudioFormat (const String& name, const StringArray& extensions)
: formatName (name), : formatName (name),
fileExtensions (extensions) fileExtensions (extensions)
{ {
@@ -518,16 +42,6 @@ AudioFormat::~AudioFormat()
} }
//============================================================================== //==============================================================================
const String& AudioFormat::getFormatName() const
{
return formatName;
}
const StringArray& AudioFormat::getFileExtensions() const
{
return fileExtensions;
}
bool AudioFormat::canHandleFile (const File& f) bool AudioFormat::canHandleFile (const File& f)
{ {
for (int i = 0; i < fileExtensions.size(); ++i) for (int i = 0; i < fileExtensions.size(); ++i)
@@ -537,15 +51,10 @@ bool AudioFormat::canHandleFile (const File& f)
return false; return false;
} }
bool AudioFormat::isCompressed()
{
return false;
}
const StringArray AudioFormat::getQualityOptions()
{
return StringArray();
}
const String& AudioFormat::getFormatName() const { return formatName; }
const StringArray& AudioFormat::getFileExtensions() const { return fileExtensions; }
bool AudioFormat::isCompressed() { return false; }
const StringArray AudioFormat::getQualityOptions() { return StringArray(); }
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 367
- 0
src/audio/audio_file_formats/juce_AudioFormatReader.cpp View File

@@ -0,0 +1,367 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioFormat.h"
#include "../dsp/juce_AudioSampleBuffer.h"
//==============================================================================
AudioFormatReader::AudioFormatReader (InputStream* const in,
const String& formatName_)
: sampleRate (0),
bitsPerSample (0),
lengthInSamples (0),
numChannels (0),
usesFloatingPointData (false),
input (in),
formatName (formatName_)
{
}
AudioFormatReader::~AudioFormatReader()
{
delete input;
}
bool AudioFormatReader::read (int* const* destSamples,
int numDestChannels,
int64 startSampleInSource,
int numSamplesToRead,
const bool fillLeftoverChannelsWithCopies)
{
jassert (numDestChannels > 0); // you have to actually give this some channels to work with!
int startOffsetInDestBuffer = 0;
if (startSampleInSource < 0)
{
const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead);
for (int i = numDestChannels; --i >= 0;)
if (destSamples[i] != 0)
zeromem (destSamples[i], sizeof (int) * silence);
startOffsetInDestBuffer += silence;
numSamplesToRead -= silence;
startSampleInSource = 0;
}
if (numSamplesToRead <= 0)
return true;
if (! readSamples (const_cast<int**> (destSamples),
jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer,
startSampleInSource, numSamplesToRead))
return false;
if (numDestChannels > (int) numChannels)
{
if (fillLeftoverChannelsWithCopies)
{
int* lastFullChannel = destSamples[0];
for (int i = (int) numChannels; --i > 0;)
{
if (destSamples[i] != 0)
{
lastFullChannel = destSamples[i];
break;
}
}
if (lastFullChannel != 0)
for (int i = numChannels; i < numDestChannels; ++i)
if (destSamples[i] != 0)
memcpy (destSamples[i], lastFullChannel, sizeof (int) * numSamplesToRead);
}
else
{
for (int i = numChannels; i < numDestChannels; ++i)
if (destSamples[i] != 0)
zeromem (destSamples[i], sizeof (int) * numSamplesToRead);
}
}
return true;
}
static void findAudioBufferMaxMin (const float* const buffer, const int num, float& maxVal, float& minVal) throw()
{
float mn = buffer[0];
float mx = mn;
for (int i = 1; i < num; ++i)
{
const float s = buffer[i];
if (s > mx) mx = s;
if (s < mn) mn = s;
}
maxVal = mx;
minVal = mn;
}
void AudioFormatReader::readMaxLevels (int64 startSampleInFile,
int64 numSamples,
float& lowestLeft, float& highestLeft,
float& lowestRight, float& highestRight)
{
if (numSamples <= 0)
{
lowestLeft = 0;
lowestRight = 0;
highestLeft = 0;
highestRight = 0;
return;
}
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
HeapBlock<int> tempSpace (bufferSize * 2 + 64);
int* tempBuffer[3];
tempBuffer[0] = tempSpace.getData();
tempBuffer[1] = tempSpace.getData() + bufferSize;
tempBuffer[2] = 0;
if (usesFloatingPointData)
{
float lmin = 1.0e6f;
float lmax = -lmin;
float rmin = lmin;
float rmax = lmax;
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
read (tempBuffer, 2, startSampleInFile, numToDo, false);
numSamples -= numToDo;
startSampleInFile += numToDo;
float bufmin, bufmax;
findAudioBufferMaxMin (reinterpret_cast<float*> (tempBuffer[0]), numToDo, bufmax, bufmin);
lmin = jmin (lmin, bufmin);
lmax = jmax (lmax, bufmax);
if (numChannels > 1)
{
findAudioBufferMaxMin (reinterpret_cast<float*> (tempBuffer[1]), numToDo, bufmax, bufmin);
rmin = jmin (rmin, bufmin);
rmax = jmax (rmax, bufmax);
}
}
if (numChannels <= 1)
{
rmax = lmax;
rmin = lmin;
}
lowestLeft = lmin;
highestLeft = lmax;
lowestRight = rmin;
highestRight = rmax;
}
else
{
int lmax = std::numeric_limits<int>::min();
int lmin = std::numeric_limits<int>::max();
int rmax = std::numeric_limits<int>::min();
int rmin = std::numeric_limits<int>::max();
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
read (tempBuffer, 2, startSampleInFile, numToDo, false);
numSamples -= numToDo;
startSampleInFile += numToDo;
for (int j = numChannels; --j >= 0;)
{
int bufMax = std::numeric_limits<int>::min();
int bufMin = std::numeric_limits<int>::max();
const int* const b = tempBuffer[j];
for (int i = 0; i < numToDo; ++i)
{
const int samp = b[i];
if (samp < bufMin)
bufMin = samp;
if (samp > bufMax)
bufMax = samp;
}
if (j == 0)
{
lmax = jmax (lmax, bufMax);
lmin = jmin (lmin, bufMin);
}
else
{
rmax = jmax (rmax, bufMax);
rmin = jmin (rmin, bufMin);
}
}
}
if (numChannels <= 1)
{
rmax = lmax;
rmin = lmin;
}
lowestLeft = lmin / (float) std::numeric_limits<int>::max();
highestLeft = lmax / (float) std::numeric_limits<int>::max();
lowestRight = rmin / (float) std::numeric_limits<int>::max();
highestRight = rmax / (float) std::numeric_limits<int>::max();
}
}
int64 AudioFormatReader::searchForLevel (int64 startSample,
int64 numSamplesToSearch,
const double magnitudeRangeMinimum,
const double magnitudeRangeMaximum,
const int minimumConsecutiveSamples)
{
if (numSamplesToSearch == 0)
return -1;
const int bufferSize = 4096;
HeapBlock<int> tempSpace (bufferSize * 2 + 64);
int* tempBuffer[3];
tempBuffer[0] = tempSpace.getData();
tempBuffer[1] = tempSpace.getData() + bufferSize;
tempBuffer[2] = 0;
int consecutive = 0;
int64 firstMatchPos = -1;
jassert (magnitudeRangeMaximum > magnitudeRangeMinimum);
const double doubleMin = jlimit (0.0, (double) std::numeric_limits<int>::max(), magnitudeRangeMinimum * std::numeric_limits<int>::max());
const double doubleMax = jlimit (doubleMin, (double) std::numeric_limits<int>::max(), magnitudeRangeMaximum * std::numeric_limits<int>::max());
const int intMagnitudeRangeMinimum = roundToInt (doubleMin);
const int intMagnitudeRangeMaximum = roundToInt (doubleMax);
while (numSamplesToSearch != 0)
{
const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize);
int64 bufferStart = startSample;
if (numSamplesToSearch < 0)
bufferStart -= numThisTime;
if (bufferStart >= (int) lengthInSamples)
break;
read (tempBuffer, 2, bufferStart, numThisTime, false);
int num = numThisTime;
while (--num >= 0)
{
if (numSamplesToSearch < 0)
--startSample;
bool matches = false;
const int index = (int) (startSample - bufferStart);
if (usesFloatingPointData)
{
const float sample1 = std::abs (((float*) tempBuffer[0]) [index]);
if (sample1 >= magnitudeRangeMinimum
&& sample1 <= magnitudeRangeMaximum)
{
matches = true;
}
else if (numChannels > 1)
{
const float sample2 = std::abs (((float*) tempBuffer[1]) [index]);
matches = (sample2 >= magnitudeRangeMinimum
&& sample2 <= magnitudeRangeMaximum);
}
}
else
{
const int sample1 = abs (tempBuffer[0] [index]);
if (sample1 >= intMagnitudeRangeMinimum
&& sample1 <= intMagnitudeRangeMaximum)
{
matches = true;
}
else if (numChannels > 1)
{
const int sample2 = abs (tempBuffer[1][index]);
matches = (sample2 >= intMagnitudeRangeMinimum
&& sample2 <= intMagnitudeRangeMaximum);
}
}
if (matches)
{
if (firstMatchPos < 0)
firstMatchPos = startSample;
if (++consecutive >= minimumConsecutiveSamples)
{
if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples)
return -1;
return firstMatchPos;
}
}
else
{
consecutive = 0;
firstMatchPos = -1;
}
if (numSamplesToSearch > 0)
++startSample;
}
if (numSamplesToSearch > 0)
numSamplesToSearch -= numThisTime;
else
numSamplesToSearch += numThisTime;
}
return -1;
}
END_JUCE_NAMESPACE

+ 272
- 0
src/audio/audio_file_formats/juce_AudioFormatWriter.cpp View File

@@ -0,0 +1,272 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioFormat.h"
#include "../dsp/juce_AudioSampleBuffer.h"
#include "../../containers/juce_AbstractFifo.h"
//==============================================================================
AudioFormatWriter::AudioFormatWriter (OutputStream* const out,
const String& formatName_,
const double rate,
const unsigned int numChannels_,
const unsigned int bitsPerSample_)
: sampleRate (rate),
numChannels (numChannels_),
bitsPerSample (bitsPerSample_),
usesFloatingPointData (false),
output (out),
formatName (formatName_)
{
}
AudioFormatWriter::~AudioFormatWriter()
{
delete output;
}
bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
int64 startSample,
int64 numSamplesToRead)
{
const int bufferSize = 16384;
AudioSampleBuffer tempBuffer (numChannels, bufferSize);
int* buffers [128];
zerostruct (buffers);
for (int i = tempBuffer.getNumChannels(); --i >= 0;)
buffers[i] = reinterpret_cast<int*> (tempBuffer.getSampleData (i, 0));
if (numSamplesToRead < 0)
numSamplesToRead = reader.lengthInSamples;
while (numSamplesToRead > 0)
{
const int numToDo = (int) jmin (numSamplesToRead, (int64) bufferSize);
if (! reader.read (buffers, numChannels, startSample, numToDo, false))
return false;
if (reader.usesFloatingPointData != isFloatingPoint())
{
int** bufferChan = buffers;
while (*bufferChan != 0)
{
int* b = *bufferChan++;
if (isFloatingPoint())
{
// int -> float
const double factor = 1.0 / std::numeric_limits<int>::max();
for (int i = 0; i < numToDo; ++i)
((float*) b)[i] = (float) (factor * b[i]);
}
else
{
// float -> int
for (int i = 0; i < numToDo; ++i)
{
const double samp = *(const float*) b;
if (samp <= -1.0)
*b++ = std::numeric_limits<int>::min();
else if (samp >= 1.0)
*b++ = std::numeric_limits<int>::max();
else
*b++ = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}
}
if (! write (const_cast<const int**> (buffers), numToDo))
return false;
numSamplesToRead -= numToDo;
startSample += numToDo;
}
return true;
}
bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, int numSamplesToRead, const int samplesPerBlock)
{
AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock);
while (numSamplesToRead > 0)
{
const int numToDo = jmin (numSamplesToRead, samplesPerBlock);
AudioSourceChannelInfo info;
info.buffer = &tempBuffer;
info.startSample = 0;
info.numSamples = numToDo;
info.clearActiveBufferRegion();
source.getNextAudioBlock (info);
if (! writeFromAudioSampleBuffer (tempBuffer, 0, numToDo))
return false;
numSamplesToRead -= numToDo;
}
return true;
}
bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples)
{
jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && source.getNumChannels() > 0);
if (numSamples <= 0)
return true;
HeapBlock<int> tempBuffer;
HeapBlock<int*> chans (numChannels + 1);
chans [numChannels] = 0;
if (isFloatingPoint())
{
for (int i = numChannels; --i >= 0;)
chans[i] = reinterpret_cast<int*> (source.getSampleData (i, startSample));
}
else
{
tempBuffer.malloc (numSamples * numChannels);
for (unsigned int i = 0; i < numChannels; ++i)
{
typedef AudioData::Pointer <AudioData::Int32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> DestSampleType;
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceSampleType;
DestSampleType destData (chans[i] = tempBuffer + i * numSamples);
SourceSampleType sourceData (source.getSampleData (i, startSample));
destData.convertSamples (sourceData, numSamples);
}
}
return write ((const int**) chans.getData(), numSamples);
}
//==============================================================================
class AudioFormatWriter::ThreadedWriter::Buffer : public TimeSliceClient,
public AbstractFifo
{
public:
Buffer (TimeSliceThread& timeSliceThread_, AudioFormatWriter* writer_, int numChannels, int bufferSize)
: AbstractFifo (bufferSize),
buffer (numChannels, bufferSize),
timeSliceThread (timeSliceThread_),
writer (writer_), isRunning (true)
{
timeSliceThread.addTimeSliceClient (this);
}
~Buffer()
{
isRunning = false;
timeSliceThread.removeTimeSliceClient (this);
while (useTimeSlice())
{}
}
bool write (const float** data, int numSamples)
{
if (numSamples <= 0 || ! isRunning)
return true;
jassert (timeSliceThread.isThreadRunning()); // you need to get your thread running before pumping data into this!
int start1, size1, start2, size2;
prepareToWrite (numSamples, start1, size1, start2, size2);
if (size1 + size2 < numSamples)
return false;
for (int i = buffer.getNumChannels(); --i >= 0;)
{
buffer.copyFrom (i, start1, data[i], size1);
buffer.copyFrom (i, start2, data[i] + size1, size2);
}
finishedWrite (size1 + size2);
timeSliceThread.notify();
return true;
}
bool useTimeSlice()
{
const int numToDo = getTotalSize() / 4;
int start1, size1, start2, size2;
prepareToRead (numToDo, start1, size1, start2, size2);
if (size1 <= 0)
return false;
writer->writeFromAudioSampleBuffer (buffer, start1, size1);
if (size2 > 0)
writer->writeFromAudioSampleBuffer (buffer, start2, size2);
finishedRead (size1 + size2);
return true;
}
private:
AudioSampleBuffer buffer;
TimeSliceThread& timeSliceThread;
ScopedPointer<AudioFormatWriter> writer;
volatile bool isRunning;
Buffer (const Buffer&);
Buffer& operator= (const Buffer&);
};
AudioFormatWriter::ThreadedWriter::ThreadedWriter (AudioFormatWriter* writer, TimeSliceThread& backgroundThread, int numSamplesToBuffer)
: buffer (new AudioFormatWriter::ThreadedWriter::Buffer (backgroundThread, writer, writer->numChannels, numSamplesToBuffer))
{
}
AudioFormatWriter::ThreadedWriter::~ThreadedWriter()
{
}
bool AudioFormatWriter::ThreadedWriter::write (const float** data, int numSamples)
{
return buffer->write (data, numSamples);
}
END_JUCE_NAMESPACE

+ 57
- 2
src/audio/audio_file_formats/juce_AudioFormatWriter.h View File

@@ -29,6 +29,7 @@
#include "../../io/files/juce_FileOutputStream.h" #include "../../io/files/juce_FileOutputStream.h"
#include "juce_AudioFormatReader.h" #include "juce_AudioFormatReader.h"
#include "../audio_sources/juce_AudioSource.h" #include "../audio_sources/juce_AudioSource.h"
#include "../../threads/juce_TimeSliceThread.h"
//============================================================================== //==============================================================================
@@ -127,6 +128,13 @@ public:
int numSamplesToRead, int numSamplesToRead,
int samplesPerBlock = 2048); int samplesPerBlock = 2048);
/** Writes some samples from an AudioSampleBuffer.
*/
bool writeFromAudioSampleBuffer (const AudioSampleBuffer& source,
int startSample, int numSamples);
//============================================================================== //==============================================================================
/** Returns the sample rate being used. */ /** Returns the sample rate being used. */
double getSampleRate() const throw() { return sampleRate; } double getSampleRate() const throw() { return sampleRate; }
@@ -140,6 +148,47 @@ public:
/** Returns true if it's a floating-point format, false if it's fixed-point. */ /** Returns true if it's a floating-point format, false if it's fixed-point. */
bool isFloatingPoint() const throw() { return usesFloatingPointData; } bool isFloatingPoint() const throw() { return usesFloatingPointData; }
//==============================================================================
/**
Provides a FIFO for an AudioFormatWriter, allowing you to push incoming
data into a buffer which will be flushed to disk by a background thread.
*/
class ThreadedWriter
{
public:
/** Creates a ThreadedWriter for a given writer and a thread.
The writer object which is passed in here will be owned and deleted by
the ThreadedWriter when it is no longer needed.
To stop the writer and flush the buffer to disk, simply delete this object.
*/
ThreadedWriter (AudioFormatWriter* writer,
TimeSliceThread& backgroundThread,
int numSamplesToBuffer);
/** Destructor. */
~ThreadedWriter();
/** Pushes some incoming audio data into the FIFO.
If there's enough free space in the buffer, this will add the data to it,
If the FIFO is too full to accept this many samples, the method will return
false - then you could either wait until the background thread has had time to
consume some of the buffered data and try again, or you can give up
and lost this block.
The data must be an array containing the same number of channels as the
AudioFormatWriter object is using. None of these channels can be null.
*/
bool write (const float** data, int numSamples);
private:
class Buffer;
friend class ScopedPointer<Buffer>;
ScopedPointer<Buffer> buffer;
};
//============================================================================== //==============================================================================
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -172,10 +221,16 @@ protected:
for (int i = 0; i < numDestChannels; ++i) for (int i = 0; i < numDestChannels; ++i)
{ {
const DestType dest (addBytesToPointer (destData, i * DestType::getBytesPerSample()), numDestChannels); const DestType dest (addBytesToPointer (destData, i * DestType::getBytesPerSample()), numDestChannels);
dest.convertSamples (SourceType (*source), numSamples);
if (source[1] != 0)
if (*source != 0)
{
dest.convertSamples (SourceType (*source), numSamples);
++source; ++source;
}
else
{
dest.clearSamples (numSamples);
}
} }
} }
}; };


+ 5
- 17
src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp View File

@@ -411,20 +411,13 @@ const Array <int> OggVorbisAudioFormat::getPossibleSampleRates()
const Array <int> OggVorbisAudioFormat::getPossibleBitDepths() const Array <int> OggVorbisAudioFormat::getPossibleBitDepths()
{ {
Array <int> depths;
depths.add (32);
return depths;
const int depths[] = { 32, 0 };
return Array <int> (depths);
} }
bool OggVorbisAudioFormat::canDoStereo()
{
return true;
}
bool OggVorbisAudioFormat::canDoMono()
{
return true;
}
bool OggVorbisAudioFormat::canDoStereo() { return true; }
bool OggVorbisAudioFormat::canDoMono() { return true; }
bool OggVorbisAudioFormat::isCompressed() { return true; }
AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in, AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in,
const bool deleteStreamIfOpeningFails) const bool deleteStreamIfOpeningFails)
@@ -456,11 +449,6 @@ AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out,
return w->ok ? w.release() : 0; return w->ok ? w.release() : 0;
} }
bool OggVorbisAudioFormat::isCompressed()
{
return true;
}
const StringArray OggVorbisAudioFormat::getQualityOptions() const StringArray OggVorbisAudioFormat::getQualityOptions()
{ {
StringArray s; StringArray s;


+ 4
- 18
src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp View File

@@ -342,25 +342,11 @@ QuickTimeAudioFormat::~QuickTimeAudioFormat()
{ {
} }
const Array <int> QuickTimeAudioFormat::getPossibleSampleRates()
{
return Array<int>();
}
const Array <int> QuickTimeAudioFormat::getPossibleBitDepths()
{
return Array<int>();
}
const Array <int> QuickTimeAudioFormat::getPossibleSampleRates() { return Array<int>(); }
const Array <int> QuickTimeAudioFormat::getPossibleBitDepths() { return Array<int>(); }
bool QuickTimeAudioFormat::canDoStereo()
{
return true;
}
bool QuickTimeAudioFormat::canDoMono()
{
return true;
}
bool QuickTimeAudioFormat::canDoStereo() { return true; }
bool QuickTimeAudioFormat::canDoMono() { return true; }
//============================================================================== //==============================================================================
AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream, AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream,


+ 2
- 39
src/audio/dsp/juce_AudioSampleBuffer.cpp View File

@@ -633,45 +633,8 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer,
const int startSample, const int startSample,
const int numSamples) const const int numSamples) const
{ {
jassert (startSample >= 0 && startSample + numSamples <= size && numChannels > 0);
if (numSamples > 0)
{
HeapBlock<int> tempBuffer;
HeapBlock<int*> chans (numChannels + 1);
chans [numChannels] = 0;
if (writer->isFloatingPoint())
{
for (int i = numChannels; --i >= 0;)
chans[i] = reinterpret_cast<int*> (channels[i] + startSample);
}
else
{
tempBuffer.malloc (numSamples * numChannels);
for (int j = 0; j < numChannels; ++j)
{
int* const dest = tempBuffer + j * numSamples;
const float* const src = channels[j] + startSample;
chans[j] = dest;
for (int i = 0; i < numSamples; ++i)
{
const double samp = src[i];
if (samp <= -1.0)
dest[i] = std::numeric_limits<int>::min();
else if (samp >= 1.0)
dest[i] = std::numeric_limits<int>::max();
else
dest[i] = roundToInt (std::numeric_limits<int>::max() * samp);
}
}
}
writer->write ((const int**) chans.getData(), numSamples);
}
jassert (writer != 0);
writer->writeFromAudioSampleBuffer (*this, startSample, numSamples);
} }
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 123
- 0
src/containers/juce_AbstractFifo.cpp View File

@@ -0,0 +1,123 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AbstractFifo.h"
//==============================================================================
AbstractFifo::AbstractFifo (const int capacity) throw()
: bufferSize (capacity)
{
jassert (bufferSize > 0);
}
AbstractFifo::~AbstractFifo() {}
int AbstractFifo::getTotalSize() const throw() { return bufferSize; }
int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); }
int AbstractFifo::getNumReady() const throw() { return validEnd.get() - validStart.get(); }
void AbstractFifo::reset() throw()
{
validEnd = 0;
validStart = 0;
}
void AbstractFifo::setTotalSize (int newSize) throw()
{
jassert (newSize > 0);
reset();
bufferSize = newSize;
}
//==============================================================================
void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw()
{
const int vs = validStart.get();
const int ve = validEnd.get();
const int freeSpace = bufferSize - (ve - vs);
numToWrite = jmin (numToWrite, freeSpace);
if (numToWrite <= 0)
{
startIndex1 = 0;
startIndex2 = 0;
blockSize1 = 0;
blockSize2 = 0;
}
else
{
startIndex1 = (int) (ve % bufferSize);
startIndex2 = 0;
blockSize1 = jmin (bufferSize - startIndex1, numToWrite);
numToWrite -= blockSize1;
blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, (int) (vs % bufferSize));
}
}
void AbstractFifo::finishedWrite (int numWritten) throw()
{
jassert (numWritten >= 0 && numWritten < bufferSize);
validEnd += numWritten;
}
void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw()
{
const int vs = validStart.get();
const int ve = validEnd.get();
const int numReady = ve - vs;
numWanted = jmin (numWanted, numReady);
if (numWanted <= 0)
{
startIndex1 = 0;
startIndex2 = 0;
blockSize1 = 0;
blockSize2 = 0;
}
else
{
startIndex1 = (int) (vs % bufferSize);
startIndex2 = 0;
blockSize1 = jmin (bufferSize - startIndex1, numWanted);
numWanted -= blockSize1;
blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, (int) (ve % bufferSize));
}
}
void AbstractFifo::finishedRead (int numRead) throw()
{
jassert (numRead >= 0 && numRead < bufferSize);
validStart += numRead;
}
END_JUCE_NAMESPACE

+ 220
- 0
src/containers/juce_AbstractFifo.h View File

@@ -0,0 +1,220 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_ABSTRACTFIFO_JUCEHEADER__
#define __JUCE_ABSTRACTFIFO_JUCEHEADER__
#include "../core/juce_Atomic.h"
//==============================================================================
/**
Encapsulates the logic required to implement a lock-free FIFO.
This class handles the logic needed when building a single-reader, single-writer FIFO.
It doesn't actually hold any data itself, but your FIFO class can use one of these to manage
its position and status when reading or writing to it.
To use it, you can call prepareToWrite() to determine the position within your own buffer that
an incoming block of data should be stored, and prepareToRead() to find out when the next
outgoing block should be read from.
e.g.
@code
class MyFifo
{
public:
MyFifo() : abstractFifo (1024)
{
}
void addToFifo (const int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToWrite (numItems, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (myBuffer + start1, someData, size1);
if (size2 > 0)
copySomeData (myBuffer + start2, someData + size1, size2);
finishedWrite (size1 + size2);
}
void readFromFifo (int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToRead (numSamples, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (someData, myBuffer + start1, size1);
if (size2 > 0)
copySomeData (someData + size1, myBuffer + start2, size2);
finishedRead (size1 + size2);
}
private:
AbstractFifo abstractFifo;
int myBuffer [1024];
};
@endcode
*/
class JUCE_API AbstractFifo
{
public:
//==============================================================================
/** Creates a FIFO to manage a buffer with the specified capacity. */
AbstractFifo (int capacity) throw();
/** Destructor */
~AbstractFifo();
//==============================================================================
/** Returns the total size of the buffer being managed. */
int getTotalSize() const throw();
/** Returns the number of items that can currently be added to the buffer without it overflowing. */
int getFreeSpace() const throw();
/** Returns the number of items that can currently be read from the buffer. */
int getNumReady() const throw();
/** Clears the buffer positions, so that it appears empty. */
void reset() throw();
/** Changes the buffer's total size.
Note that this isn't thread-safe, so don't call it if there's any danger that it
might overlap with a call to any other method in this class!
*/
void setTotalSize (int newSize) throw();
//==============================================================================
/** Returns the location within the buffer at which an incoming block of data should be written.
Because the section of data that you want to add to the buffer may overlap the end
and wrap around to the start, two blocks within your buffer are returned, and you
should copy your data into the first one, with any remaining data spilling over into
the second.
If the number of items you ask for is too large to fit within the buffer's free space, then
blockSize1 + blockSize2 may add up to a lower value than numToWrite.
After calling this method, and writing your data, you must call finishedWrite() to tell the
FIFO how much data you actually added.
e.g.
@code
void addToFifo (const int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToWrite (numItems, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (myBuffer + start1, someData, size1);
if (size2 > 0)
copySomeData (myBuffer + start2, someData + size1, size2);
finishedWrite (size1 + size2);
}
@endcode
@param numToWrite indicates how many items you'd like to add to the buffer
@param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1
@param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into
the first block should be written
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex2
@see finishedWrite
*/
void prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw();
/** Called after reading from the FIFO, to indicate that this many items have been added.
@see prepareToWrite
*/
void finishedWrite (int numWritten) throw();
/** Returns the location within the buffer from which the next block of data should be read.
Because the section of data that you want to read from the buffer may overlap the end
and wrap around to the start, two blocks within your buffer are returned, and you
should read from both of them.
If the number of items you ask for is greater than the amount of data available, then
blockSize1 + blockSize2 may add up to a lower value than numWanted.
After calling this method, and reading the data, you must call finishedRead() to tell the
FIFO how much data you have consumed.
e.g.
@code
void readFromFifo (int* someData, int numItems)
{
int start1, size1, start2, size2;
prepareToRead (numSamples, start1, size1, start2, size2);
if (size1 > 0)
copySomeData (someData, myBuffer + start1, size1);
if (size2 > 0)
copySomeData (someData + size1, myBuffer + start2, size2);
finishedRead (size1 + size2);
}
@endcode
@param numToWrite indicates how many items you'd like to add to the buffer
@param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1
@param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into
the first block should be written
@param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex2
@see finishedRead
*/
void prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) throw();
/** Called after reading from the FIFO, to indicate that this many items have now been consumed.
@see prepareToRead
*/
void finishedRead (int numRead) throw();
//==============================================================================
juce_UseDebuggingNewOperator
private:
int bufferSize;
Atomic <int> validStart, validEnd;
AbstractFifo (const AbstractFifo&);
AbstractFifo& operator= (const AbstractFifo&);
};
#endif // __JUCE_ABSTRACTFIFO_JUCEHEADER__

+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52 #define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 70
#define JUCE_BUILDNUMBER 71
/** Current Juce version number. /** Current Juce version number.


+ 3
- 0
src/juce_core_includes.h View File

@@ -26,6 +26,9 @@
#ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ #ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
#define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ #define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
#ifndef __JUCE_ABSTRACTFIFO_JUCEHEADER__
#include "containers/juce_AbstractFifo.h"
#endif
#ifndef __JUCE_ARRAY_JUCEHEADER__ #ifndef __JUCE_ARRAY_JUCEHEADER__
#include "containers/juce_Array.h" #include "containers/juce_Array.h"
#endif #endif


Loading…
Cancel
Save