mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
WavAudioFormat: Add support for writing 32 bit integral (PCM) format
This commit is contained in:
parent
34675235e5
commit
386daafe23
43 changed files with 677 additions and 125 deletions
|
|
@ -525,6 +525,7 @@ add_library( ${BINARY_NAME}
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
@ -3184,6 +3185,7 @@ set_source_files_properties(
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
|
||||||
|
|
@ -3558,6 +3558,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4974,6 +4974,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -3558,6 +3558,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4974,6 +4974,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -480,6 +480,7 @@ add_library( ${BINARY_NAME}
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
@ -2753,6 +2754,7 @@ set_source_files_properties(
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
|
||||||
|
|
@ -3072,6 +3072,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4236,6 +4236,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -513,6 +513,7 @@ add_library( ${BINARY_NAME}
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
@ -2939,6 +2940,7 @@ set_source_files_properties(
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
|
||||||
|
|
@ -3252,6 +3252,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4512,6 +4512,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -3252,6 +3252,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4512,6 +4512,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -484,6 +484,7 @@ add_library( ${BINARY_NAME}
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
@ -2837,6 +2838,7 @@ set_source_files_properties(
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"
|
||||||
|
"../../../../../modules/juce_audio_formats/format/juce_AudioFormatWriterOptions.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
"../../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"
|
||||||
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
"../../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"
|
||||||
|
|
|
||||||
|
|
@ -3163,6 +3163,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4377,6 +4377,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -3364,6 +3364,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4671,6 +4671,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -3364,6 +3364,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4671,6 +4671,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -3139,6 +3139,7 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatReaderSource.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h"/>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_BufferingAudioFormatReader.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_MemoryMappedAudioFormatReader.h"/>
|
||||||
|
|
|
||||||
|
|
@ -4344,6 +4344,9 @@
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriter.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioFormatWriterOptions.h">
|
||||||
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
<ClInclude Include="..\..\..\..\modules\juce_audio_formats\format\juce_AudioSubsectionReader.h">
|
||||||
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
<Filter>JUCE Modules\juce_audio_formats\format</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -1031,4 +1031,20 @@ AudioFormatWriter* AiffAudioFormat::createWriterFor (OutputStream* out,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> AiffAudioFormat::createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options)
|
||||||
|
{
|
||||||
|
if (streamToWriteTo == nullptr || ! getPossibleBitDepths().contains (options.getBitsPerSample()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
StringPairArray metadata;
|
||||||
|
metadata.addUnorderedMap (options.getMetadataValues());
|
||||||
|
|
||||||
|
return std::make_unique<AiffAudioFormatWriter> (std::exchange (streamToWriteTo, {}).release(),
|
||||||
|
options.getSampleRate(),
|
||||||
|
(unsigned int) options.getNumChannels(),
|
||||||
|
(unsigned int) options.getBitsPerSample(),
|
||||||
|
metadata);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ public:
|
||||||
int bitsPerSample,
|
int bitsPerSample,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex) override;
|
int qualityOptionIndex) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -665,6 +665,13 @@ AudioFormatWriter* CoreAudioFormat::createWriterFor (OutputStream*,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> CoreAudioFormat::createWriterFor (std::unique_ptr<OutputStream>&,
|
||||||
|
const AudioFormatWriterOptions&)
|
||||||
|
{
|
||||||
|
jassertfalse; // not yet implemented!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,10 @@ public:
|
||||||
int bitsPerSample,
|
int bitsPerSample,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex) override;
|
int qualityOptionIndex) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -610,7 +610,7 @@ AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
|
||||||
if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample))
|
if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample))
|
||||||
{
|
{
|
||||||
std::unique_ptr<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels,
|
std::unique_ptr<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels,
|
||||||
(uint32) bitsPerSample, qualityOptionIndex));
|
(uint32) bitsPerSample, qualityOptionIndex));
|
||||||
if (w->ok)
|
if (w->ok)
|
||||||
return w.release();
|
return w.release();
|
||||||
}
|
}
|
||||||
|
|
@ -618,6 +618,24 @@ AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> FlacAudioFormat::createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options)
|
||||||
|
{
|
||||||
|
if (streamToWriteTo == nullptr || ! getPossibleBitDepths().contains (options.getBitsPerSample()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto writer = std::make_unique<FlacWriter> (std::exchange (streamToWriteTo, {}).release(),
|
||||||
|
options.getSampleRate(),
|
||||||
|
(uint32) options.getNumChannels(),
|
||||||
|
(uint32) options.getBitsPerSample(),
|
||||||
|
options.getQualityOptionIndex());
|
||||||
|
|
||||||
|
if (! writer->ok)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
StringArray FlacAudioFormat::getQualityOptions()
|
StringArray FlacAudioFormat::getQualityOptions()
|
||||||
{
|
{
|
||||||
return { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)" };
|
return { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)" };
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@ public:
|
||||||
StringArray getQualityOptions() override;
|
StringArray getQualityOptions() override;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
||||||
bool deleteStreamIfOpeningFails) override;
|
bool deleteStreamIfOpeningFails) override;
|
||||||
|
|
||||||
|
|
@ -72,6 +75,7 @@ public:
|
||||||
int bitsPerSample,
|
int bitsPerSample,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex) override;
|
int qualityOptionIndex) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -50,36 +50,39 @@ public:
|
||||||
{
|
{
|
||||||
WavAudioFormat wavFormat;
|
WavAudioFormat wavFormat;
|
||||||
|
|
||||||
if (auto out = tempWav.getFile().createOutputStream())
|
writer = wavFormat.createWriterFor (tempWav.getFile().createOutputStream(),
|
||||||
|
AudioFormatWriter::Options{}.withSampleRate (sampleRateIn)
|
||||||
|
.withNumChannels ((int) numberOfChannels)
|
||||||
|
.withBitsPerSample (bitsPerSampleIn)
|
||||||
|
.withMetadataValues (metadata));
|
||||||
|
|
||||||
|
if (writer == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.add (appFile.getFullPathName());
|
||||||
|
|
||||||
|
args.add ("--quiet");
|
||||||
|
|
||||||
|
if (cbrBitrate == 0)
|
||||||
{
|
{
|
||||||
writer.reset (wavFormat.createWriterFor (out.release(), sampleRateIn, numChannels,
|
args.add ("--vbr-new");
|
||||||
bitsPerSampleIn, metadata, 0));
|
args.add ("-V");
|
||||||
|
args.add (String (vbrLevel));
|
||||||
args.add (appFile.getFullPathName());
|
|
||||||
|
|
||||||
args.add ("--quiet");
|
|
||||||
|
|
||||||
if (cbrBitrate == 0)
|
|
||||||
{
|
|
||||||
args.add ("--vbr-new");
|
|
||||||
args.add ("-V");
|
|
||||||
args.add (String (vbrLevel));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args.add ("--cbr");
|
|
||||||
args.add ("-b");
|
|
||||||
args.add (String (cbrBitrate));
|
|
||||||
}
|
|
||||||
|
|
||||||
addMetadataArg (metadata, "id3title", "--tt");
|
|
||||||
addMetadataArg (metadata, "id3artist", "--ta");
|
|
||||||
addMetadataArg (metadata, "id3album", "--tl");
|
|
||||||
addMetadataArg (metadata, "id3comment", "--tc");
|
|
||||||
addMetadataArg (metadata, "id3date", "--ty");
|
|
||||||
addMetadataArg (metadata, "id3genre", "--tg");
|
|
||||||
addMetadataArg (metadata, "id3trackNumber", "--tn");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args.add ("--cbr");
|
||||||
|
args.add ("-b");
|
||||||
|
args.add (String (cbrBitrate));
|
||||||
|
}
|
||||||
|
|
||||||
|
addMetadataArg (metadata, "id3title", "--tt");
|
||||||
|
addMetadataArg (metadata, "id3artist", "--ta");
|
||||||
|
addMetadataArg (metadata, "id3album", "--tl");
|
||||||
|
addMetadataArg (metadata, "id3comment", "--tc");
|
||||||
|
addMetadataArg (metadata, "id3date", "--ty");
|
||||||
|
addMetadataArg (metadata, "id3genre", "--tg");
|
||||||
|
addMetadataArg (metadata, "id3trackNumber", "--tn");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag)
|
void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag)
|
||||||
|
|
@ -165,10 +168,6 @@ LAMEEncoderAudioFormat::LAMEEncoderAudioFormat (const File& lameApplication)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LAMEEncoderAudioFormat::~LAMEEncoderAudioFormat()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LAMEEncoderAudioFormat::canHandleFile (const File&)
|
bool LAMEEncoderAudioFormat::canHandleFile (const File&)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -208,6 +207,33 @@ AudioFormatReader* LAMEEncoderAudioFormat::createReaderFor (InputStream*, const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> LAMEEncoderAudioFormat::createWriterFor (std::unique_ptr<OutputStream> streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options)
|
||||||
|
{
|
||||||
|
if (streamToWriteTo == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
int vbr = 4;
|
||||||
|
int cbr = 0;
|
||||||
|
|
||||||
|
const String qual (getQualityOptions() [options.getQualityOptionIndex()]);
|
||||||
|
|
||||||
|
if (qual.contains ("VBR"))
|
||||||
|
vbr = qual.retainCharacters ("0123456789").getIntValue();
|
||||||
|
else
|
||||||
|
cbr = qual.getIntValue();
|
||||||
|
|
||||||
|
return std::make_unique<Writer> (streamToWriteTo.release(),
|
||||||
|
getFormatName(),
|
||||||
|
lameApp,
|
||||||
|
vbr,
|
||||||
|
cbr,
|
||||||
|
options.getSampleRate(),
|
||||||
|
(unsigned int) options.getNumChannels(),
|
||||||
|
options.getBitsPerSample(),
|
||||||
|
options.getMetadataValues());
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormatWriter* LAMEEncoderAudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
AudioFormatWriter* LAMEEncoderAudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
||||||
double sampleRateToUse,
|
double sampleRateToUse,
|
||||||
unsigned int numberOfChannels,
|
unsigned int numberOfChannels,
|
||||||
|
|
|
||||||
|
|
@ -60,21 +60,24 @@ public:
|
||||||
executable at the location given.
|
executable at the location given.
|
||||||
*/
|
*/
|
||||||
LAMEEncoderAudioFormat (const File& lameExecutableToUse);
|
LAMEEncoderAudioFormat (const File& lameExecutableToUse);
|
||||||
~LAMEEncoderAudioFormat();
|
|
||||||
|
|
||||||
bool canHandleFile (const File&);
|
bool canHandleFile (const File&) override;
|
||||||
Array<int> getPossibleSampleRates();
|
Array<int> getPossibleSampleRates() override;
|
||||||
Array<int> getPossibleBitDepths();
|
Array<int> getPossibleBitDepths() override;
|
||||||
bool canDoStereo();
|
bool canDoStereo() override;
|
||||||
bool canDoMono();
|
bool canDoMono() override;
|
||||||
bool isCompressed();
|
bool isCompressed() override;
|
||||||
StringArray getQualityOptions();
|
StringArray getQualityOptions() override;
|
||||||
|
|
||||||
AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails);
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream> streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
|
AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override;
|
||||||
|
|
||||||
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
||||||
unsigned int numberOfChannels, int bitsPerSample,
|
unsigned int numberOfChannels, int bitsPerSample,
|
||||||
const StringPairArray& metadataValues, int qualityOptionIndex);
|
const StringPairArray& metadataValues, int qualityOptionIndex);
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -3173,6 +3173,13 @@ AudioFormatReader* MP3AudioFormat::createReaderFor (InputStream* sourceStream, c
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> MP3AudioFormat::createWriterFor (std::unique_ptr<OutputStream>&,
|
||||||
|
const AudioFormatWriterOptions&)
|
||||||
|
{
|
||||||
|
jassertfalse; // not yet implemented!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormatWriter* MP3AudioFormat::createWriterFor (OutputStream*, double /*sampleRateToUse*/,
|
AudioFormatWriter* MP3AudioFormat::createWriterFor (OutputStream*, double /*sampleRateToUse*/,
|
||||||
unsigned int /*numberOfChannels*/, int /*bitsPerSample*/,
|
unsigned int /*numberOfChannels*/, int /*bitsPerSample*/,
|
||||||
const StringPairArray& /*metadataValues*/, int /*qualityOptionIndex*/)
|
const StringPairArray& /*metadataValues*/, int /*qualityOptionIndex*/)
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,10 @@ public:
|
||||||
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
||||||
unsigned int numberOfChannels, int bitsPerSample,
|
unsigned int numberOfChannels, int bitsPerSample,
|
||||||
const StringPairArray& metadataValues, int qualityOptionIndex) override;
|
const StringPairArray& metadataValues, int qualityOptionIndex) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -463,6 +463,28 @@ AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in, bool
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> OggVorbisAudioFormat::createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options)
|
||||||
|
{
|
||||||
|
if (streamToWriteTo == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
StringPairArray metadata;
|
||||||
|
metadata.addUnorderedMap (options.getMetadataValues());
|
||||||
|
|
||||||
|
auto w = std::make_unique<OggWriter> (std::exchange (streamToWriteTo, {}).release(),
|
||||||
|
options.getSampleRate(),
|
||||||
|
(unsigned int) options.getNumChannels(),
|
||||||
|
(unsigned int) options.getBitsPerSample(),
|
||||||
|
options.getQualityOptionIndex(),
|
||||||
|
metadata);
|
||||||
|
|
||||||
|
if (! w->ok)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out,
|
AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out,
|
||||||
double sampleRate,
|
double sampleRate,
|
||||||
unsigned int numChannels,
|
unsigned int numChannels,
|
||||||
|
|
|
||||||
|
|
@ -93,12 +93,16 @@ public:
|
||||||
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
||||||
bool deleteStreamIfOpeningFails) override;
|
bool deleteStreamIfOpeningFails) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
||||||
double sampleRateToUse,
|
double sampleRateToUse,
|
||||||
unsigned int numberOfChannels,
|
unsigned int numberOfChannels,
|
||||||
int bitsPerSample,
|
int bitsPerSample,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex) override;
|
int qualityOptionIndex) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,6 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
using StringMap = std::unordered_map<String, String>;
|
|
||||||
|
|
||||||
static auto toMap (const StringPairArray& array)
|
|
||||||
{
|
|
||||||
StringMap result;
|
|
||||||
|
|
||||||
for (auto i = 0; i < array.size(); ++i)
|
|
||||||
result[array.getAllKeys()[i]] = array.getAllValues()[i];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto getValueWithDefault (const StringMap& m, const String& key, const String& fallback = {})
|
static auto getValueWithDefault (const StringMap& m, const String& key, const String& fallback = {})
|
||||||
{
|
{
|
||||||
const auto iter = m.find (key);
|
const auto iter = m.find (key);
|
||||||
|
|
@ -1599,30 +1587,36 @@ class WavAudioFormatWriter final : public AudioFormatWriter
|
||||||
public:
|
public:
|
||||||
WavAudioFormatWriter (OutputStream* const out, const double rate,
|
WavAudioFormatWriter (OutputStream* const out, const double rate,
|
||||||
const AudioChannelSet& channelLayoutToUse, const unsigned int bits,
|
const AudioChannelSet& channelLayoutToUse, const unsigned int bits,
|
||||||
const StringPairArray& metadataValues)
|
const StringMap& metadataValues,
|
||||||
|
AudioFormatWriterOptions::SampleFormat sampleFormat)
|
||||||
: AudioFormatWriter (out, wavFormatName, rate, channelLayoutToUse, bits)
|
: AudioFormatWriter (out, wavFormatName, rate, channelLayoutToUse, bits)
|
||||||
{
|
{
|
||||||
using namespace WavFileHelpers;
|
using namespace WavFileHelpers;
|
||||||
|
using SampleFormat = AudioFormatWriterOptions::SampleFormat;
|
||||||
|
|
||||||
if (metadataValues.size() > 0)
|
// The floating point format is only supported with a bit depth of 32
|
||||||
|
jassert (sampleFormat != SampleFormat::floatingPoint || bits == 32);
|
||||||
|
|
||||||
|
usesFloatingPointData = bits == 32 && sampleFormat != SampleFormat::integral;
|
||||||
|
|
||||||
|
if (! metadataValues.empty())
|
||||||
{
|
{
|
||||||
// The meta data should have been sanitised for the WAV format.
|
// The meta data should have been sanitised for the WAV format.
|
||||||
// If it was originally sourced from an AIFF file the MetaDataSource
|
// If it was originally sourced from an AIFF file the MetaDataSource
|
||||||
// key should be removed (or set to "WAV") once this has been done
|
// key should be removed (or set to "WAV") once this has been done
|
||||||
jassert (metadataValues.getValue ("MetaDataSource", "None") != "AIFF");
|
jassert (metadataValues.count ("MetaDataSource") == 0
|
||||||
|
|| metadataValues.at ("MetaDataSource") != "AIFF");
|
||||||
|
|
||||||
const auto map = toMap (metadataValues);
|
bwavChunk = BWAVChunk::createFrom (metadataValues);
|
||||||
|
ixmlChunk = IXMLChunk::createFrom (metadataValues);
|
||||||
bwavChunk = BWAVChunk::createFrom (map);
|
axmlChunk = AXMLChunk::createFrom (metadataValues);
|
||||||
ixmlChunk = IXMLChunk::createFrom (map);
|
smplChunk = SMPLChunk::createFrom (metadataValues);
|
||||||
axmlChunk = AXMLChunk::createFrom (map);
|
instChunk = InstChunk::createFrom (metadataValues);
|
||||||
smplChunk = SMPLChunk::createFrom (map);
|
cueChunk = CueChunk ::createFrom (metadataValues);
|
||||||
instChunk = InstChunk::createFrom (map);
|
listChunk = ListChunk::createFrom (metadataValues);
|
||||||
cueChunk = CueChunk ::createFrom (map);
|
listInfoChunk = ListInfoChunk::createFrom (metadataValues);
|
||||||
listChunk = ListChunk::createFrom (map);
|
acidChunk = AcidChunk::createFrom (metadataValues);
|
||||||
listInfoChunk = ListInfoChunk::createFrom (map);
|
trckChunk = TracktionChunk::createFrom (metadataValues);
|
||||||
acidChunk = AcidChunk::createFrom (map);
|
|
||||||
trckChunk = TracktionChunk::createFrom (map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
headerPosition = out->getPosition();
|
headerPosition = out->getPosition();
|
||||||
|
|
@ -1773,8 +1767,12 @@ private:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeChunkHeader (chunkName ("fmt "), 16);
|
writeChunkHeader (chunkName ("fmt "), 16);
|
||||||
output->writeShort (bitsPerSample < 32 ? (short) 1 /*WAVE_FORMAT_PCM*/
|
|
||||||
: (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/);
|
constexpr short waveFormatIeeeFloat = 3;
|
||||||
|
constexpr short waveFormatPcm = 1;
|
||||||
|
|
||||||
|
output->writeShort (usesFloatingPointData ? waveFormatIeeeFloat
|
||||||
|
: waveFormatPcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
output->writeShort ((short) numChannels);
|
output->writeShort ((short) numChannels);
|
||||||
|
|
@ -1789,7 +1787,7 @@ private:
|
||||||
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
|
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
|
||||||
output->writeInt (channelMask);
|
output->writeInt (channelMask);
|
||||||
|
|
||||||
const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
|
const ExtensibleWavSubFormat& subFormat = usesFloatingPointData ? IEEEFloatFormat : pcmFormat;
|
||||||
|
|
||||||
output->writeInt ((int) subFormat.data1);
|
output->writeInt ((int) subFormat.data1);
|
||||||
output->writeShort ((short) subFormat.data2);
|
output->writeShort ((short) subFormat.data2);
|
||||||
|
|
@ -1809,8 +1807,6 @@ private:
|
||||||
writeChunk (trckChunk, chunkName ("Trkn"));
|
writeChunk (trckChunk, chunkName ("Trkn"));
|
||||||
|
|
||||||
writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame));
|
writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame));
|
||||||
|
|
||||||
usesFloatingPointData = (bitsPerSample == 32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t chunkSize (const MemoryBlock& data) noexcept { return data.isEmpty() ? 0 : (8 + data.getSize()); }
|
static size_t chunkSize (const MemoryBlock& data) noexcept { return data.isEmpty() ? 0 : (8 + data.getSize()); }
|
||||||
|
|
@ -2027,6 +2023,25 @@ MemoryMappedAudioFormatReader* WavAudioFormat::createMemoryMappedReader (FileInp
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> WavAudioFormat::createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options)
|
||||||
|
{
|
||||||
|
if (streamToWriteTo == nullptr || ! getPossibleBitDepths().contains (options.getBitsPerSample()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto layout = options.getChannelLayout().value_or (WavFileHelpers::canonicalWavChannelSet (options.getNumChannels()));
|
||||||
|
|
||||||
|
if (! isChannelLayoutSupported (layout))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return std::make_unique<WavAudioFormatWriter> (std::exchange (streamToWriteTo, {}).release(),
|
||||||
|
options.getSampleRate(),
|
||||||
|
layout,
|
||||||
|
(unsigned int) options.getBitsPerSample(),
|
||||||
|
options.getMetadataValues(),
|
||||||
|
options.getSampleFormat());
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, double sampleRate,
|
AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, double sampleRate,
|
||||||
unsigned int numChannels, int bitsPerSample,
|
unsigned int numChannels, int bitsPerSample,
|
||||||
const StringPairArray& metadataValues, int qualityOptionIndex)
|
const StringPairArray& metadataValues, int qualityOptionIndex)
|
||||||
|
|
@ -2044,44 +2059,39 @@ AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out,
|
||||||
{
|
{
|
||||||
if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample) && isChannelLayoutSupported (channelLayout))
|
if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample) && isChannelLayoutSupported (channelLayout))
|
||||||
return new WavAudioFormatWriter (out, sampleRate, channelLayout,
|
return new WavAudioFormatWriter (out, sampleRate, channelLayout,
|
||||||
(unsigned int) bitsPerSample, metadataValues);
|
(unsigned int) bitsPerSample, toMap (metadataValues),
|
||||||
|
AudioFormatWriterOptions::SampleFormat::automatic);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace WavFileHelpers
|
namespace WavFileHelpers
|
||||||
{
|
{
|
||||||
static bool slowCopyWavFileWithNewMetadata (const File& file, const StringPairArray& metadata)
|
static bool slowCopyWavFileWithNewMetadata (const File& file, const StringMap& metadata)
|
||||||
{
|
{
|
||||||
TemporaryFile tempFile (file);
|
TemporaryFile tempFile (file);
|
||||||
WavAudioFormat wav;
|
WavAudioFormat wav;
|
||||||
|
|
||||||
std::unique_ptr<AudioFormatReader> reader (wav.createReaderFor (file.createInputStream().release(), true));
|
std::unique_ptr<AudioFormatReader> reader (wav.createReaderFor (file.createInputStream().release(), true));
|
||||||
|
|
||||||
if (reader != nullptr)
|
if (reader == nullptr)
|
||||||
{
|
return false;
|
||||||
std::unique_ptr<OutputStream> outStream (tempFile.getFile().createOutputStream());
|
|
||||||
|
|
||||||
if (outStream != nullptr)
|
std::unique_ptr<OutputStream> stream = tempFile.getFile().createOutputStream();
|
||||||
{
|
auto writer = wav.createWriterFor (stream,
|
||||||
std::unique_ptr<AudioFormatWriter> writer (wav.createWriterFor (outStream.get(), reader->sampleRate,
|
AudioFormatWriter::Options{}.withSampleRate (reader->sampleRate)
|
||||||
reader->numChannels, (int) reader->bitsPerSample,
|
.withNumChannels ((int) reader->numChannels)
|
||||||
metadata, 0));
|
.withBitsPerSample ((int) reader->bitsPerSample)
|
||||||
|
.withMetadataValues (metadata));
|
||||||
|
|
||||||
if (writer != nullptr)
|
if (writer == nullptr)
|
||||||
{
|
return false;
|
||||||
outStream.release();
|
|
||||||
|
|
||||||
bool ok = writer->writeFromAudioReader (*reader, 0, -1);
|
bool ok = writer->writeFromAudioReader (*reader, 0, -1);
|
||||||
writer.reset();
|
writer.reset();
|
||||||
reader.reset();
|
reader.reset();
|
||||||
|
|
||||||
return ok && tempFile.overwriteTargetFileWithTemporary();
|
return ok && tempFile.overwriteTargetFileWithTemporary();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2123,7 +2133,7 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return slowCopyWavFileWithNewMetadata (wavFile, newMetadata);
|
return slowCopyWavFileWithNewMetadata (wavFile, toMap (newMetadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2172,15 +2182,14 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
{
|
{
|
||||||
beginTest ("Metadata can be written and read");
|
beginTest ("Metadata can be written and read");
|
||||||
|
|
||||||
const auto newMetadata = getMetadataAfterReading (format, writeToBlock (format, metadataArray));
|
const auto newMetadata = getMetadataAfterReading (format, writeToBlock (format, metadataValues));
|
||||||
expect (newMetadata == metadataArray, "Somehow, the metadata is different!");
|
expect (newMetadata == metadataArray, "Somehow, the metadata is different!");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
beginTest ("Files containing a riff info source and an empty ISRC associate the source with the riffInfoSource key");
|
beginTest ("Files containing a riff info source and an empty ISRC associate the source with the riffInfoSource key");
|
||||||
StringPairArray meta;
|
StringMap meta { { WavAudioFormat::riffInfoSource, "customsource" },
|
||||||
meta.addMap ({ { WavAudioFormat::riffInfoSource, "customsource" },
|
{ WavAudioFormat::internationalStandardRecordingCode, "" } };
|
||||||
{ WavAudioFormat::internationalStandardRecordingCode, "" } });
|
|
||||||
const auto mb = writeToBlock (format, meta);
|
const auto mb = writeToBlock (format, meta);
|
||||||
checkPatternsPresent (mb, { "INFOISRC" });
|
checkPatternsPresent (mb, { "INFOISRC" });
|
||||||
checkPatternsNotPresent (mb, { "ISRC:", "<ebucore" });
|
checkPatternsNotPresent (mb, { "ISRC:", "<ebucore" });
|
||||||
|
|
@ -2192,8 +2201,7 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
{
|
{
|
||||||
beginTest ("Files containing a riff info source and no ISRC associate the source with both keys "
|
beginTest ("Files containing a riff info source and no ISRC associate the source with both keys "
|
||||||
"for backwards compatibility");
|
"for backwards compatibility");
|
||||||
StringPairArray meta;
|
StringMap meta { { WavAudioFormat::riffInfoSource, "customsource" } };
|
||||||
meta.addMap ({ { WavAudioFormat::riffInfoSource, "customsource" } });
|
|
||||||
const auto mb = writeToBlock (format, meta);
|
const auto mb = writeToBlock (format, meta);
|
||||||
checkPatternsPresent (mb, { "INFOISRC", "ISRC:customsource", "<ebucore" });
|
checkPatternsPresent (mb, { "INFOISRC", "ISRC:customsource", "<ebucore" });
|
||||||
const auto a = getMetadataAfterReading (format, mb);
|
const auto a = getMetadataAfterReading (format, mb);
|
||||||
|
|
@ -2204,8 +2212,7 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
{
|
{
|
||||||
beginTest ("Files containing an ISRC associate the value with the internationalStandardRecordingCode key "
|
beginTest ("Files containing an ISRC associate the value with the internationalStandardRecordingCode key "
|
||||||
"and the riffInfoSource key for backwards compatibility");
|
"and the riffInfoSource key for backwards compatibility");
|
||||||
StringPairArray meta;
|
StringMap meta { { WavAudioFormat::internationalStandardRecordingCode, "AABBBCCDDDDD" } };
|
||||||
meta.addMap ({ { WavAudioFormat::internationalStandardRecordingCode, "AABBBCCDDDDD" } });
|
|
||||||
const auto mb = writeToBlock (format, meta);
|
const auto mb = writeToBlock (format, meta);
|
||||||
checkPatternsPresent (mb, { "ISRC:AABBBCCDDDDD", "<ebucore" });
|
checkPatternsPresent (mb, { "ISRC:AABBBCCDDDDD", "<ebucore" });
|
||||||
checkPatternsNotPresent (mb, { "INFOISRC" });
|
checkPatternsNotPresent (mb, { "INFOISRC" });
|
||||||
|
|
@ -2216,9 +2223,8 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
|
|
||||||
{
|
{
|
||||||
beginTest ("Files containing an ISRC and a riff info source associate the values with the appropriate keys");
|
beginTest ("Files containing an ISRC and a riff info source associate the values with the appropriate keys");
|
||||||
StringPairArray meta;
|
StringMap meta { { WavAudioFormat::riffInfoSource, "source" },
|
||||||
meta.addMap ({ { WavAudioFormat::riffInfoSource, "source" } });
|
{ WavAudioFormat::internationalStandardRecordingCode, "UUVVVXXYYYYY" } };
|
||||||
meta.addMap ({ { WavAudioFormat::internationalStandardRecordingCode, "UUVVVXXYYYYY" } });
|
|
||||||
const auto mb = writeToBlock (format, meta);
|
const auto mb = writeToBlock (format, meta);
|
||||||
checkPatternsPresent (mb, { "INFOISRC", "ISRC:UUVVVXXYYYYY", "<ebucore" });
|
checkPatternsPresent (mb, { "INFOISRC", "ISRC:UUVVVXXYYYYY", "<ebucore" });
|
||||||
const auto a = getMetadataAfterReading (format, mb);
|
const auto a = getMetadataAfterReading (format, mb);
|
||||||
|
|
@ -2229,13 +2235,19 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
{
|
{
|
||||||
beginTest ("Files containing ASWG metadata read and write correctly");
|
beginTest ("Files containing ASWG metadata read and write correctly");
|
||||||
MemoryBlock block;
|
MemoryBlock block;
|
||||||
StringPairArray meta;
|
StringMap meta;
|
||||||
|
|
||||||
for (const auto& key : WavFileHelpers::IXMLChunk::aswgMetadataKeys)
|
for (const auto& key : WavFileHelpers::IXMLChunk::aswgMetadataKeys)
|
||||||
meta.set (key, "Test123&<>");
|
meta[key] = "Test123&<>";
|
||||||
|
|
||||||
{
|
{
|
||||||
auto writer = rawToUniquePtr (WavAudioFormat().createWriterFor (new MemoryOutputStream (block, false), 48000, 1, 32, meta, 0));
|
const auto writerOptions = AudioFormatWriterOptions{}.withSampleRate (48000.0)
|
||||||
|
.withNumChannels (1)
|
||||||
|
.withBitsPerSample (32)
|
||||||
|
.withMetadataValues (meta);
|
||||||
|
|
||||||
|
std::unique_ptr<OutputStream> stream = std::make_unique<MemoryOutputStream> (block, false);
|
||||||
|
auto writer = format.createWriterFor (stream, writerOptions);
|
||||||
expect (writer != nullptr);
|
expect (writer != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2270,9 +2282,8 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
auto reader = rawToUniquePtr (WavAudioFormat().createReaderFor (new MemoryInputStream (block, false), true));
|
auto reader = rawToUniquePtr (WavAudioFormat().createReaderFor (new MemoryInputStream (block, false), true));
|
||||||
expect (reader != nullptr);
|
expect (reader != nullptr);
|
||||||
|
|
||||||
for (const auto& key : meta.getAllKeys())
|
for (const auto& [key, oldValue] : meta)
|
||||||
{
|
{
|
||||||
const auto oldValue = meta.getValue (key, "!");
|
|
||||||
const auto newValue = reader->metadataValues.getValue (key, "");
|
const auto newValue = reader->metadataValues.getValue (key, "");
|
||||||
expectEquals (oldValue, newValue);
|
expectEquals (oldValue, newValue);
|
||||||
}
|
}
|
||||||
|
|
@ -2280,22 +2291,128 @@ struct WaveAudioFormatTests final : public UnitTest
|
||||||
expect (reader->metadataValues.getValue (WavAudioFormat::aswgVersion, "") == "3.01");
|
expect (reader->metadataValues.getValue (WavAudioFormat::aswgVersion, "") == "3.01");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
beginTest ("Writing 32-bit integer samples should work");
|
||||||
|
|
||||||
|
const auto minimum = std::numeric_limits<int>::min();
|
||||||
|
const auto maximum = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
|
std::vector<int> dataIn { minimum,
|
||||||
|
minimum + 1,
|
||||||
|
minimum + 999,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
maximum - 1001,
|
||||||
|
maximum - 1,
|
||||||
|
maximum };
|
||||||
|
|
||||||
|
const int* ptr = dataIn.data();
|
||||||
|
|
||||||
|
WavFormatWriterTestData integralTestData { &ptr,
|
||||||
|
dataIn.size(),
|
||||||
|
AudioFormatWriterOptions::SampleFormat::integral };
|
||||||
|
|
||||||
|
auto* reader = integralTestData.getReader();
|
||||||
|
|
||||||
|
if (reader == nullptr)
|
||||||
|
{
|
||||||
|
expect (false, "WavFormatReader should be non-null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> dataOut ((size_t) reader->lengthInSamples);
|
||||||
|
int* const outPtr = dataOut.data();
|
||||||
|
reader->read (&outPtr, 1, 0, (int) dataOut.size(), false);
|
||||||
|
|
||||||
|
expect (reader->usesFloatingPointData == false);
|
||||||
|
expect (dataIn == dataOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
beginTest ("Writing 32-bit float samples should work");
|
||||||
|
|
||||||
|
std::vector<float> dataIn { -1.0f,
|
||||||
|
-0.8f,
|
||||||
|
0.0f,
|
||||||
|
0.8f,
|
||||||
|
1.0f };
|
||||||
|
|
||||||
|
const int* ptr = (int*) dataIn.data();
|
||||||
|
|
||||||
|
WavFormatWriterTestData floatingPointTestData { &ptr,
|
||||||
|
dataIn.size(),
|
||||||
|
AudioFormatWriterOptions::SampleFormat::floatingPoint };
|
||||||
|
|
||||||
|
auto* reader = floatingPointTestData.getReader();
|
||||||
|
|
||||||
|
if (reader == nullptr)
|
||||||
|
{
|
||||||
|
expect (false, "WavFormatReader should be non-null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> dataOut ((size_t) reader->lengthInSamples);
|
||||||
|
float* const outPtr = dataOut.data();
|
||||||
|
reader->read (&outPtr, 1, 0, (int) dataOut.size());
|
||||||
|
|
||||||
|
expect (reader->usesFloatingPointData == true);
|
||||||
|
expect (dataIn.size() == dataOut.size());
|
||||||
|
|
||||||
|
for (auto [index, value] : enumerate (dataOut, size_t{}))
|
||||||
|
expect (approximatelyEqual (value, dataIn[index]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryBlock writeToBlock (WavAudioFormat& format, StringPairArray meta)
|
struct WavFormatWriterTestData
|
||||||
|
{
|
||||||
|
WavFormatWriterTestData (const int** ptr,
|
||||||
|
size_t numSamples,
|
||||||
|
AudioFormatWriterOptions::SampleFormat sampleFormat)
|
||||||
|
{
|
||||||
|
const auto writerOptions = AudioFormatWriterOptions{}.withSampleRate (48000.0)
|
||||||
|
.withNumChannels (1)
|
||||||
|
.withBitsPerSample (32)
|
||||||
|
.withSampleFormat (sampleFormat);
|
||||||
|
|
||||||
|
WavAudioFormat format;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_ptr<OutputStream> stream = std::make_unique<MemoryOutputStream> (block, false);
|
||||||
|
auto writer = format.createWriterFor (stream, writerOptions);
|
||||||
|
|
||||||
|
writer->write (ptr, (int) numSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader = rawToUniquePtr (format.createReaderFor (new MemoryInputStream (block, false), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioFormatReader* getReader()
|
||||||
|
{
|
||||||
|
return reader.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryBlock block;
|
||||||
|
std::unique_ptr<AudioFormatReader> reader;
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryBlock writeToBlock (WavAudioFormat& format, const StringMap& meta)
|
||||||
{
|
{
|
||||||
MemoryBlock mb;
|
MemoryBlock mb;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const auto writerOptions = AudioFormatWriterOptions{}.withSampleRate (44100.0)
|
||||||
|
.withNumChannels ((int) numTestAudioBufferChannels)
|
||||||
|
.withBitsPerSample (16)
|
||||||
|
.withMetadataValues (meta);
|
||||||
|
|
||||||
// The destructor of the writer will modify the block, so make sure that we've
|
// The destructor of the writer will modify the block, so make sure that we've
|
||||||
// destroyed the writer before returning the block!
|
// destroyed the writer before returning the block!
|
||||||
auto writer = rawToUniquePtr (format.createWriterFor (new MemoryOutputStream (mb, false),
|
std::unique_ptr<OutputStream> stream = std::make_unique<MemoryOutputStream> (mb, false);
|
||||||
44100.0,
|
auto writer = format.createWriterFor (stream, writerOptions);
|
||||||
numTestAudioBufferChannels,
|
|
||||||
16,
|
|
||||||
meta,
|
|
||||||
0));
|
|
||||||
expect (writer != nullptr);
|
expect (writer != nullptr);
|
||||||
AudioBuffer<float> buffer (numTestAudioBufferChannels, numTestAudioBufferSamples);
|
AudioBuffer<float> buffer (numTestAudioBufferChannels, numTestAudioBufferSamples);
|
||||||
expect (writer->writeFromAudioSampleBuffer (buffer, 0, numTestAudioBufferSamples));
|
expect (writer->writeFromAudioSampleBuffer (buffer, 0, numTestAudioBufferSamples));
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,9 @@ public:
|
||||||
MemoryMappedAudioFormatReader* createMemoryMappedReader (const File&) override;
|
MemoryMappedAudioFormatReader* createMemoryMappedReader (const File&) override;
|
||||||
MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream*) override;
|
MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream*) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
||||||
double sampleRateToUse,
|
double sampleRateToUse,
|
||||||
unsigned int numberOfChannels,
|
unsigned int numberOfChannels,
|
||||||
|
|
@ -310,6 +313,7 @@ public:
|
||||||
int bitsPerSample,
|
int bitsPerSample,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex) override;
|
int qualityOptionIndex) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,13 @@ AudioFormatWriter* WindowsMediaAudioFormat::createWriterFor (OutputStream* /*str
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> WindowsMediaAudioFormat::createWriterFor (std::unique_ptr<OutputStream>&,
|
||||||
|
const AudioFormatWriterOptions&)
|
||||||
|
{
|
||||||
|
jassertfalse; // not yet implemented!
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#if JUCE_UNIT_TESTS
|
#if JUCE_UNIT_TESTS
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,13 @@ public:
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override;
|
AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) override;
|
||||||
|
|
||||||
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse,
|
||||||
unsigned int numberOfChannels, int bitsPerSample,
|
unsigned int numberOfChannels, int bitsPerSample,
|
||||||
const StringPairArray& metadataValues, int qualityOptionIndex) override;
|
const StringPairArray& metadataValues, int qualityOptionIndex) override;
|
||||||
|
|
||||||
using AudioFormat::createWriterFor;
|
using AudioFormat::createWriterFor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,53 @@ bool AudioFormat::isChannelLayoutSupported (const AudioChannelSet& channelSet)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using StringMap = std::unordered_map<String, String>;
|
||||||
|
|
||||||
|
static StringMap toMap (const StringPairArray& array)
|
||||||
|
{
|
||||||
|
StringMap result;
|
||||||
|
|
||||||
|
for (auto i = 0; i < array.size(); ++i)
|
||||||
|
result[array.getAllKeys()[i]] = array.getAllValues()[i];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioFormatWriter* AudioFormat::createWriterForRawPtr (OutputStream* streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& opt)
|
||||||
|
{
|
||||||
|
auto owned = rawToUniquePtr (streamToWriteTo);
|
||||||
|
|
||||||
|
if (auto writer = createWriterFor (owned, opt))
|
||||||
|
{
|
||||||
|
// Creating the writer succeeded, so it's the writer's responsibility to eventually free
|
||||||
|
// the stream
|
||||||
|
jassert (owned == nullptr);
|
||||||
|
return writer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating the writer failed, so the stream should remain alive for re-use
|
||||||
|
jassert (owned != nullptr);
|
||||||
|
owned.release();
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioFormatWriter* AudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
||||||
|
double sampleRateToUse,
|
||||||
|
unsigned int numberOfChannels,
|
||||||
|
int bitsPerSample,
|
||||||
|
const StringPairArray& metadataValues,
|
||||||
|
int qualityOptionIndex)
|
||||||
|
{
|
||||||
|
auto opt = AudioFormatWriter::Options{}.withSampleRate (sampleRateToUse)
|
||||||
|
.withNumChannels ((int) numberOfChannels)
|
||||||
|
.withBitsPerSample (bitsPerSample)
|
||||||
|
.withMetadataValues (toMap (metadataValues))
|
||||||
|
.withQualityOptionIndex (qualityOptionIndex);
|
||||||
|
return createWriterForRawPtr (streamToWriteTo, opt);
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormatWriter* AudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
AudioFormatWriter* AudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
||||||
double sampleRateToUse,
|
double sampleRateToUse,
|
||||||
const AudioChannelSet& channelLayout,
|
const AudioChannelSet& channelLayout,
|
||||||
|
|
@ -89,12 +136,15 @@ AudioFormatWriter* AudioFormat::createWriterFor (OutputStream* streamToWriteTo,
|
||||||
const StringPairArray& metadataValues,
|
const StringPairArray& metadataValues,
|
||||||
int qualityOptionIndex)
|
int qualityOptionIndex)
|
||||||
{
|
{
|
||||||
if (isChannelLayoutSupported (channelLayout))
|
if (! isChannelLayoutSupported (channelLayout))
|
||||||
return createWriterFor (streamToWriteTo, sampleRateToUse,
|
return nullptr;
|
||||||
static_cast<unsigned int> (channelLayout.size()),
|
|
||||||
bitsPerSample, metadataValues, qualityOptionIndex);
|
|
||||||
|
|
||||||
return nullptr;
|
auto opt = AudioFormatWriter::Options{}.withSampleRate (sampleRateToUse)
|
||||||
|
.withChannelLayout (channelLayout)
|
||||||
|
.withBitsPerSample (bitsPerSample)
|
||||||
|
.withMetadataValues (toMap (metadataValues))
|
||||||
|
.withQualityOptionIndex (qualityOptionIndex);
|
||||||
|
return createWriterForRawPtr (streamToWriteTo, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,26 @@ public:
|
||||||
virtual MemoryMappedAudioFormatReader* createMemoryMappedReader (const File& file);
|
virtual MemoryMappedAudioFormatReader* createMemoryMappedReader (const File& file);
|
||||||
virtual MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream* fin);
|
virtual MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream* fin);
|
||||||
|
|
||||||
|
/** Tries to create an object that can write to a stream with this audio format.
|
||||||
|
|
||||||
|
If the writer can't be created for some reason (e.g. the parameters passed in
|
||||||
|
here aren't suitable), this will return nullptr.
|
||||||
|
|
||||||
|
@param streamToWriteTo a reference to a unique_ptr that owns the output stream. If creating
|
||||||
|
the writer succeeds, then ownership of the stream will be
|
||||||
|
transferred to the writer, and this argument will be set to nullptr.
|
||||||
|
If creating the writer fails, then streamToWriteTo will remain
|
||||||
|
unchanged, allowing it to be reused to create a writer of a
|
||||||
|
different format.
|
||||||
|
@param options options that specify details of the output file. If the audio format
|
||||||
|
does not support these settings, then this function may return
|
||||||
|
nullptr.
|
||||||
|
|
||||||
|
@see AudioFormatWriterOptions
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<AudioFormatWriter> createWriterFor (std::unique_ptr<OutputStream>& streamToWriteTo,
|
||||||
|
const AudioFormatWriterOptions& options) = 0;
|
||||||
|
|
||||||
/** Tries to create an object that can write to a stream with this audio format.
|
/** Tries to create an object that can write to a stream with this audio format.
|
||||||
|
|
||||||
The writer object that is returned can be used to write to the stream, and
|
The writer object that is returned can be used to write to the stream, and
|
||||||
|
|
@ -217,6 +237,8 @@ protected:
|
||||||
AudioFormat (StringRef formatName, StringRef fileExtensions);
|
AudioFormat (StringRef formatName, StringRef fileExtensions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AudioFormatWriter* createWriterForRawPtr (OutputStream*, const AudioFormatWriterOptions&);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
String formatName;
|
String formatName;
|
||||||
StringArray fileExtensions;
|
StringArray fileExtensions;
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,8 @@ protected:
|
||||||
unsigned int bitsPerSample);
|
unsigned int bitsPerSample);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using Options = AudioFormatWriterOptions;
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
virtual ~AudioFormatWriter();
|
virtual ~AudioFormatWriter();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
This file is part of the JUCE framework.
|
||||||
|
Copyright (c) Raw Material Software Limited
|
||||||
|
|
||||||
|
JUCE is an open source framework subject to commercial or open source
|
||||||
|
licensing.
|
||||||
|
|
||||||
|
By downloading, installing, or using the JUCE framework, or combining the
|
||||||
|
JUCE framework with any other source code, object code, content or any other
|
||||||
|
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||||
|
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||||
|
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||||
|
do not agree to the terms of these agreements, we will not license the JUCE
|
||||||
|
framework to you, and you must discontinue the installation or download
|
||||||
|
process and cease use of the JUCE framework.
|
||||||
|
|
||||||
|
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||||
|
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||||
|
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||||
|
|
||||||
|
Or:
|
||||||
|
|
||||||
|
You may also use this code under the terms of the AGPLv3:
|
||||||
|
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
|
||||||
|
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||||
|
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||||
|
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace juce
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
Options that affect the output data format produced by an AudioFormatWriter. Format
|
||||||
|
specific writers may ignore some of these options.
|
||||||
|
|
||||||
|
@see AudioFormat::createWriterFor(), AudioFormatWriter
|
||||||
|
|
||||||
|
@tags{Audio}
|
||||||
|
*/
|
||||||
|
class JUCE_API AudioFormatWriterOptions final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Used to provide a hint to the AudioFormatWriter for the output sample format.
|
||||||
|
|
||||||
|
Use automatic for the old behaviour. The values integral and floatingPoint can be used with
|
||||||
|
the WavAudioFormat when using a bit depth of 32. Other formats are not affected by this
|
||||||
|
setting.
|
||||||
|
*/
|
||||||
|
enum class SampleFormat
|
||||||
|
{
|
||||||
|
automatic, ///< Lets the writer decide the format based on the other parameter values.
|
||||||
|
integral, ///< Integral format, e.g. PCM in case of the WavAudioFormat
|
||||||
|
floatingPoint ///< IEEE floating point format
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified sample format.
|
||||||
|
|
||||||
|
@see SampleFormat
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withSampleFormat (SampleFormat x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::sampleFormat, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified sample rate.
|
||||||
|
|
||||||
|
This specifies the sample rate for the file, which must be one of the ones
|
||||||
|
returned by AudioFormat::getPossibleSampleRates().
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withSampleRate (double x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::sampleRate, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified channel set.
|
||||||
|
|
||||||
|
Setting this option will supersede the value passed into withNumChannels().
|
||||||
|
|
||||||
|
You should prefer to use withChannelLayout(), if specifying an AudioChannelSet is
|
||||||
|
applicable, and withNumChannels() otherwise.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withChannelLayout (const AudioChannelSet& x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::channelLayout, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified number of channels.
|
||||||
|
|
||||||
|
This is meant as a fallback for specifying the channel layout. Setting this option will
|
||||||
|
have no effect if the channel layout is specified.
|
||||||
|
|
||||||
|
@see withChannelLayout()
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withNumChannels (int x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::numChannels, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified bit size per sample.
|
||||||
|
|
||||||
|
This must be one of the values returned by AudioFormat::getPossibleBitDepths().
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withBitsPerSample (int x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::bitsPerSample, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified metadata container.
|
||||||
|
|
||||||
|
As an alternative to this function, you can specify the key-value pairs one-by-one using
|
||||||
|
the withMetadata function.
|
||||||
|
|
||||||
|
Subsequent calls of this function overwrites all previously added metadata.
|
||||||
|
|
||||||
|
This parameter is a set of metadata values that the writer should try to write to the stream.
|
||||||
|
Exactly what these are depends on the format, and the subclass doesn't actually have to do
|
||||||
|
anything with them if it doesn't want to. Have a look at the specific format implementation
|
||||||
|
classes to see possible values that can be used.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withMetadataValues (const std::unordered_map<String, String>& x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::metadataValues, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified metadata added.
|
||||||
|
|
||||||
|
Subsequent calls of this function adds new metadata values, while also preserving the
|
||||||
|
previously added ones.
|
||||||
|
|
||||||
|
Here you can specify metadata values that the writer should try to write to the stream.
|
||||||
|
Exactly what these are depends on the format, and the subclass doesn't actually have to do
|
||||||
|
anything with them if it doesn't want to. Have a look at the specific format implementation
|
||||||
|
classes to see possible values that can be used.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withMetadata (const String& key, const String& value) const
|
||||||
|
{
|
||||||
|
auto copy = *this;
|
||||||
|
copy.metadataValues[key] = value;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a copy of these options with the specified quality option index.
|
||||||
|
|
||||||
|
The index of one of the items returned by the AudioFormat::getQualityOptions() method.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] AudioFormatWriterOptions withQualityOptionIndex (int x) const
|
||||||
|
{
|
||||||
|
return withMember (*this, &AudioFormatWriterOptions::qualityOptionIndex, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see withSampleRate() */
|
||||||
|
[[nodiscard]] auto getSampleRate() const { return sampleRate; }
|
||||||
|
/** @see withChannelLayout() */
|
||||||
|
[[nodiscard]] auto getChannelLayout() const { return channelLayout; }
|
||||||
|
/** @see withNumChannels() */
|
||||||
|
[[nodiscard]] auto getNumChannels() const { return channelLayout.has_value() ? channelLayout->size() : numChannels; }
|
||||||
|
/** @see withBitsPerSample() */
|
||||||
|
[[nodiscard]] auto getBitsPerSample() const { return bitsPerSample; }
|
||||||
|
/** @see withMetadataValues() */
|
||||||
|
[[nodiscard]] auto getMetadataValues() const { return metadataValues; }
|
||||||
|
/** @see withQualityOptionIndex() */
|
||||||
|
[[nodiscard]] auto getQualityOptionIndex() const { return qualityOptionIndex; }
|
||||||
|
/** @see withSampleFormat() */
|
||||||
|
[[nodiscard]] auto getSampleFormat() const { return sampleFormat; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
double sampleRate = 48000.0;
|
||||||
|
int numChannels = 1;
|
||||||
|
std::optional<AudioChannelSet> channelLayout = std::nullopt;
|
||||||
|
int bitsPerSample = 16;
|
||||||
|
std::unordered_map<String, String> metadataValues;
|
||||||
|
int qualityOptionIndex = 0;
|
||||||
|
SampleFormat sampleFormat = SampleFormat::automatic;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace juce
|
||||||
|
|
@ -121,6 +121,7 @@
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#include "format/juce_AudioFormatReader.h"
|
#include "format/juce_AudioFormatReader.h"
|
||||||
|
#include "format/juce_AudioFormatWriterOptions.h"
|
||||||
#include "format/juce_AudioFormatWriter.h"
|
#include "format/juce_AudioFormatWriter.h"
|
||||||
#include "format/juce_MemoryMappedAudioFormatReader.h"
|
#include "format/juce_MemoryMappedAudioFormatReader.h"
|
||||||
#include "format/juce_AudioFormat.h"
|
#include "format/juce_AudioFormat.h"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue