From 4aeaf8f62f5fa8eabd56388140599d37307b4f7d Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Fri, 7 Sep 2018 21:16:16 +1000 Subject: [PATCH] libopenshot_audio: add haiku audio output module --- .../libopenshot_audio-0.1.6.recipe | 2 +- .../patches/libopenshot_audio-0.1.6.patchset | 383 +++++++++++++++++- 2 files changed, 379 insertions(+), 6 deletions(-) diff --git a/media-libs/libopenshot-audio/libopenshot_audio-0.1.6.recipe b/media-libs/libopenshot-audio/libopenshot_audio-0.1.6.recipe index 0f41ef70f..e9d0e3d28 100644 --- a/media-libs/libopenshot-audio/libopenshot_audio-0.1.6.recipe +++ b/media-libs/libopenshot-audio/libopenshot_audio-0.1.6.recipe @@ -9,7 +9,7 @@ LICENSE="GNU GPL v3 GNU GPL v2 GNU AGPL v3 ISC" -REVISION="1" +REVISION="2" SOURCE_URI="https://github.com/OpenShot/libopenshot-audio/archive/v$portVersion.tar.gz" CHECKSUM_SHA256="090ed62a59f35642081f6da58677e5f8f316ed2062cb47cf0617a71678b890c3" SOURCE_FILENAME="libopenshot-audio-$portVersion.tar.gz" diff --git a/media-libs/libopenshot-audio/patches/libopenshot_audio-0.1.6.patchset b/media-libs/libopenshot-audio/patches/libopenshot_audio-0.1.6.patchset index 9669c7f42..52eea0d13 100644 --- a/media-libs/libopenshot-audio/patches/libopenshot_audio-0.1.6.patchset +++ b/media-libs/libopenshot-audio/patches/libopenshot_audio-0.1.6.patchset @@ -1,4 +1,4 @@ -From f7788f0aeef9e3fea3f17d1e398b0ac4714a1dba Mon Sep 17 00:00:00 2001 +From 7be5a99aed08e2008d4a8568c5c7f874206985a0 Mon Sep 17 00:00:00 2001 From: Leorize Date: Tue, 28 Aug 2018 16:43:43 +0700 Subject: cmake: uses GNUInstallDirs @@ -127,7 +127,7 @@ index a5ee15a..0a9f423 100644 2.16.4 -From b5fa3e84aa782e890a8923bb8772f421deffebfc Mon Sep 17 00:00:00 2001 +From 0f75001590c7cd8bb2f968d46fcaa4c188bc8e32 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Thu, 30 Aug 2018 00:22:13 +0700 Subject: Haiku patch @@ -1777,7 +1777,7 @@ index 0000000..b5c0a4d 2.16.4 -From 3d6ff53869ac0c2bf618c6ecf4a05bde37978adf Mon Sep 17 00:00:00 2001 +From 0850e5250726d5f4e19dfa5433c585d54b0b6b15 Mon Sep 17 00:00:00 2001 From: Leorize Date: Thu, 30 Aug 2018 15:20:04 +0700 Subject: cmake: fix documentation installation @@ -1803,7 +1803,7 @@ index 5c7e5f6..0c0e4e9 100644 2.16.4 -From 40cc214402b5fcc803c1f35121120913360fd046 Mon Sep 17 00:00:00 2001 +From 97b33acd27b7f49443eef6542b90101b959b4e5c Mon Sep 17 00:00:00 2001 From: Leorize Date: Thu, 30 Aug 2018 10:37:53 +0700 Subject: haiku: uses native libraries @@ -1833,7 +1833,7 @@ index 0c0e4e9..c6669e1 100644 2.16.4 -From 9ac8dff70510ea742abee32bb9ce7aca0a6f537b Mon Sep 17 00:00:00 2001 +From cf2c33e039c39cf27d75b1559d7915749516f563 Mon Sep 17 00:00:00 2001 From: Ghislain Antony Vaillant Date: Thu, 15 Dec 2016 19:39:01 +0000 Subject: Fix build with libpng16 @@ -1860,3 +1860,376 @@ index fa3b887..fe382b6 100644 -- 2.16.4 + +From 7d47f592cd7bb31749daa5529351825fbe4e6651 Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Fri, 7 Sep 2018 20:46:02 +1000 +Subject: Add Haiku audio output module + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index c6669e1..6ef07a7 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -136,7 +136,7 @@ ELSE (WIN32) + ADD_DEFINITIONS(-DHAIKU) + ADD_DEFINITIONS(${PNG_DEFINITIONS}) + ADD_DEFINITIONS(-DJUCE_INCLUDE_PNGLIB_CODE=0) +- SET(JUCE_PLATFORM_SPECIFIC_LIBRARIES ${CURL_LIBRARIES} ${FREETYPE_LIBRARIES} ${PNG_LIBRARIES}) ++ SET(JUCE_PLATFORM_SPECIFIC_LIBRARIES ${CURL_LIBRARIES} ${FREETYPE_LIBRARIES} ${PNG_LIBRARIES} -lbe -lmedia) + ELSE (HAIKU) + SET_PROPERTY(GLOBAL PROPERTY JUCE_LINUX "JUCE_LINUX") + SET(EXTENSION "cpp") +diff --git a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +index 25451fe..b946db1 100644 +--- a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp ++++ b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +@@ -163,6 +163,7 @@ void AudioDeviceManager::createAudioDeviceTypes (OwnedArray& + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android()); ++ addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Haiku()); + } + + void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType) +diff --git a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +index 0df87eb..cced450 100644 +--- a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp ++++ b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +@@ -76,3 +76,7 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() + #if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } + #endif ++ ++#if ! JUCE_HAIKU ++AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Haiku() { return nullptr; } ++#endif +diff --git a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h +index 73b8afc..a90430a 100644 +--- a/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h ++++ b/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h +@@ -164,6 +164,8 @@ public: + static AudioIODeviceType* createAudioIODeviceType_Android(); + /** Creates an Android OpenSLES device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_OpenSLES(); ++ /** Creates an Haiku device type if it's available on this platform, or returns null. */ ++ static AudioIODeviceType* createAudioIODeviceType_Haiku(); + + protected: + explicit AudioIODeviceType (const String& typeName); +diff --git a/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp b/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp +index 6c1fd00..ef8b8df 100644 +--- a/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp ++++ b/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp +@@ -92,6 +92,10 @@ + #include + #endif + ++//============================================================================== ++#elif JUCE_HAIKU ++#include ++#include + //============================================================================== + #elif JUCE_LINUX + #if JUCE_ALSA +@@ -218,6 +222,7 @@ namespace juce + //============================================================================== + #elif JUCE_HAIKU + #include "native/juce_haiku_Midi.cpp" ++ #include "native/juce_haiku_Audio.cpp" + + #if JUCE_USE_CDREADER + #include "native/juce_linux_AudioCDReader.cpp" +diff --git a/JuceLibraryCode/modules/juce_audio_devices/native/juce_haiku_Audio.cpp b/JuceLibraryCode/modules/juce_audio_devices/native/juce_haiku_Audio.cpp +new file mode 100644 +index 0000000..55f7b0b +--- /dev/null ++++ b/JuceLibraryCode/modules/juce_audio_devices/native/juce_haiku_Audio.cpp +@@ -0,0 +1,284 @@ ++/* Haiku audio output module for JUCE library. ++(c) 2018 Gerasim Troeglazov (3dEyes**)*/ ++ ++#define BUFFER_SIZE 1024 ++#define AUDIO_TYPE int16 ++#define AUDIO_RATE 44100 ++#define AUDIO_IN_CHANNELS 1 ++#define AUDIO_OUT_CHANNELS 2 ++#define AUDIO_BYTES sizeof(AUDIO_TYPE) ++#define AUDIO_BITS (AUDIO_BYTES * 8) ++ ++const char* const haikuAudioTypeName = "MediaKit Audio"; ++ ++class HaikuAudioIODevice : public AudioIODevice ++{ ++public: ++ HaikuAudioIODevice(const String& deviceName) ++ : AudioIODevice(deviceName, haikuAudioTypeName), ++ soundPlayer(NULL), ++ callback(nullptr), ++ inputChannelBuffer(1, 1), ++ outputChannelBuffer(1, 1) ++ { ++ } ++ ++ ~HaikuAudioIODevice() ++ { ++ close(); ++ } ++ ++ StringArray getOutputChannelNames() override ++ { ++ StringArray s; ++ s.add("Left"); ++ s.add("Right"); ++ return s; ++ } ++ ++ StringArray getInputChannelNames() override ++ { ++ StringArray s; ++ return s; ++ } ++ ++ Array getAvailableSampleRates() override ++ { ++ Array r; ++ r.add((double)AUDIO_RATE); ++ return r; ++ } ++ ++ Array getAvailableBufferSizes() override ++ { ++ Array b; ++ b.add(BUFFER_SIZE); ++ return b; ++ } ++ ++ int getDefaultBufferSize() override ++ { ++ return BUFFER_SIZE; ++ } ++ ++ String open(const BigInteger& inputChannels, ++ const BigInteger& outputChannels, ++ double requestedSampleRate, ++ int bufferSize) override ++ { ++ close(); ++ ++ if ((int) requestedSampleRate != AUDIO_RATE) ++ return "Sample rate not allowed"; ++ ++ lastError.clear(); ++ ++ media_raw_audio_format mediaKitFormat = { ++ (float)AUDIO_RATE, ++ (uint32)AUDIO_OUT_CHANNELS, ++ media_raw_audio_format::B_AUDIO_SHORT, ++ B_MEDIA_LITTLE_ENDIAN, ++ (uint32)BUFFER_SIZE * AUDIO_OUT_CHANNELS * AUDIO_BYTES ++ }; ++ ++ inputChannelBuffer.setSize (AUDIO_IN_CHANNELS, BUFFER_SIZE); ++ inputChannelBuffer.clear(); ++ outputChannelBuffer.setSize (AUDIO_OUT_CHANNELS, BUFFER_SIZE); ++ outputChannelBuffer.clear(); ++ ++ soundPlayer = new BSoundPlayer(&mediaKitFormat, "OpenShot", \ ++ processCallback, NULL, (void*)this); ++ ++ if (soundPlayer->InitCheck() != B_OK) { ++ delete soundPlayer; ++ soundPlayer = nullptr; ++ lastError = "BSoundPlayer not initialized"; ++ } ++ ++ return lastError; ++ } ++ ++ void close() override ++ { ++ if (soundPlayer != nullptr) { ++ soundPlayer->SetHasData(false); ++ soundPlayer->Stop(); ++ delete soundPlayer; ++ soundPlayer = nullptr; ++ } ++ } ++ ++ int getOutputLatencyInSamples() override ++ { ++ return 0; ++ } ++ ++ int getInputLatencyInSamples() override ++ { ++ return 0; ++ } ++ ++ bool isOpen() override ++ { ++ if (soundPlayer == nullptr) ++ return false; ++ if (soundPlayer->InitCheck() != B_OK) ++ return false; ++ return true; ++ } ++ ++ int getCurrentBufferSizeSamples() override ++ { ++ return BUFFER_SIZE; ++ } ++ ++ int getCurrentBitDepth() override ++ { ++ return AUDIO_BITS; ++ } ++ ++ double getCurrentSampleRate() override ++ { ++ return AUDIO_RATE; ++ } ++ ++ BigInteger getActiveOutputChannels() const override ++ { ++ return AUDIO_OUT_CHANNELS; ++ } ++ ++ BigInteger getActiveInputChannels() const override ++ { ++ return AUDIO_IN_CHANNELS; ++ } ++ ++ String getLastError() override ++ { ++ return lastError; ++ } ++ ++ bool isPlaying() override ++ { ++ if (soundPlayer == nullptr) ++ return false; ++ return soundPlayer->HasData(); ++ } ++ ++ void start(AudioIODeviceCallback* newCallback) override ++ { ++ if (soundPlayer != nullptr && callback != newCallback) { ++ if (newCallback != nullptr)newCallback->audioDeviceAboutToStart (this); ++ const ScopedLock sl (callbackLock); ++ callback = newCallback; ++ } ++ soundPlayer->Start(); ++ soundPlayer->SetHasData(true); ++ } ++ ++ void stop() override ++ { ++ soundPlayer->SetHasData(false); ++ soundPlayer->Stop(); ++ ++ outputChannelBuffer.clear(); ++ ++ if (soundPlayer != nullptr) { ++ AudioIODeviceCallback* lastCallback; ++ { ++ const ScopedLock sl (callbackLock); ++ lastCallback = callback; ++ callback = nullptr; ++ } ++ if (lastCallback != nullptr) ++ lastCallback->audioDeviceStopped(); ++ } ++ } ++ ++private: ++ void process (void *buffer, size_t len) ++ { ++ int16 *destBuffer = (int16*)buffer; ++ size_t numSamples = len / (AUDIO_OUT_CHANNELS * AUDIO_BYTES); ++ { ++ const ScopedLock sl (callbackLock); ++ if (callback != nullptr) { ++ callback->audioDeviceIOCallback (inputChannelBuffer.getArrayOfReadPointers(), AUDIO_IN_CHANNELS, ++ outputChannelBuffer.getArrayOfWritePointers(), AUDIO_OUT_CHANNELS, numSamples); ++ } else { ++ outputChannelBuffer.clear(); ++ } ++ } ++ for (int i = 0; i < AUDIO_OUT_CHANNELS; ++i) { ++ typedef AudioData::Pointer DstSampleType; ++ typedef AudioData::Pointer SrcSampleType; ++ DstSampleType dstData (destBuffer + i, AUDIO_OUT_CHANNELS); ++ SrcSampleType srcData (outputChannelBuffer.getReadPointer (i, 0)); ++ dstData.convertSamples (srcData, numSamples); ++ } ++ } ++ ++ static void processCallback(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format) ++ { ++ if (cookie != nullptr) ++ ((HaikuAudioIODevice*) cookie)->process (buffer, len); ++ else ++ zeromem(buffer, len); ++ } ++ ++ AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; ++ String lastError; ++ AudioIODeviceCallback* callback; ++ CriticalSection callbackLock; ++ BSoundPlayer *soundPlayer; ++ ++ JUCE_DECLARE_NON_COPYABLE (HaikuAudioIODevice) ++}; ++ ++ ++class HaikuAudioIODeviceType : public AudioIODeviceType ++{ ++public: ++ HaikuAudioIODeviceType() : AudioIODeviceType (haikuAudioTypeName) {} ++ ++ void scanForDevices() {} ++ ++ StringArray getDeviceNames (bool wantInputNames) const ++ { ++ return StringArray (haikuAudioTypeName); ++ } ++ ++ int getDefaultDeviceIndex (bool forInput) const ++ { ++ return 0; ++ } ++ ++ int getIndexOfDevice (AudioIODevice* device, bool asInput) const ++ { ++ return (device != nullptr && !asInput) ? 0 : -1; ++ } ++ ++ bool hasSeparateInputsAndOutputs() const ++ { ++ return true; ++ } ++ ++ AudioIODevice* createDevice (const String& outputDeviceName, const String& inputDeviceName) ++ { ++ ScopedPointer dev; ++ if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) { ++ dev = new HaikuAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName : inputDeviceName); ++ if (dev->getCurrentSampleRate() <= 0 || dev->getDefaultBufferSize() <= 0) ++ dev = nullptr; ++ } ++ return dev.release(); ++ } ++ ++private: ++ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HaikuAudioIODeviceType) ++}; ++ ++ ++AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Haiku() ++{ ++ return new HaikuAudioIODeviceType(); ++} +-- +2.16.4 +