Files
haikuports/net-im/telegram-desktop/patches/telegram_desktop-1.3.9-libtgvoip.patchset
Gerasim Troeglazov 95e67b9034 Telegram: bump version
* Export now broken. gcc7 segfault on export code.
2018-07-02 17:28:21 +10:00

1053 lines
30 KiB
Plaintext

From 15130ecca47fcbfd3e15c9ace71b00a669042202 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 10 Jun 2018 11:08:42 +1000
Subject: Fix for using external opus lib
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusDecoder.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusDecoder.h
index 6425c97..848b930 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusDecoder.h
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusDecoder.h
@@ -9,7 +9,7 @@
#include "MediaStreamItf.h"
-#include "opus.h"
+#include <opus/opus.h>
#include "threading.h"
#include "BlockingQueue.h"
#include "Buffers.h"
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusEncoder.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusEncoder.h
index 4726f6b..92d8c33 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusEncoder.h
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/OpusEncoder.h
@@ -9,7 +9,7 @@
#include "MediaStreamItf.h"
-#include "opus.h"
+#include <opus/opus.h>
#include "threading.h"
#include "BlockingQueue.h"
#include "Buffers.h"
--
2.16.4
From b4be4f2018dcc71fee9682e1f20f2a75799d9902 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 10 Jun 2018 11:10:12 +1000
Subject: Add haiku modules
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/VoIPController.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/VoIPController.cpp
index 4a1f63d..1264b01 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/VoIPController.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/VoIPController.cpp
@@ -8,6 +8,9 @@
#include <unistd.h>
#include <sys/time.h>
#endif
+#ifdef __HAIKU__
+#include <OS.h>
+#endif
#include <errno.h>
#include <string.h>
#include <wchar.h>
@@ -2403,6 +2406,10 @@ double VoIPController::GetCurrentTime(){
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec+(double)ts.tv_nsec/1000000000.0;
+#elif defined(__HAIKU__)
+ struct timeval tm;
+ gettimeofday(&tm, NULL);
+ return tm.tv_sec+(double)tm.tv_usec/1000000.0;
#elif defined(__APPLE__)
static pthread_once_t token = PTHREAD_ONCE_INIT;
pthread_once(&token, &initMachTimestart);
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioInput.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioInput.cpp
index 062ca06..887889e 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioInput.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioInput.cpp
@@ -22,6 +22,8 @@
#elif defined(__linux__)
#include "../os/linux/AudioInputALSA.h"
#include "../os/linux/AudioInputPulse.h"
+#elif defined(__HAIKU__)
+#include "../os/haiku/AudioInputHaiku.h"
#else
#error "Unsupported operating system"
#endif
@@ -64,6 +66,8 @@ AudioInput *AudioInput::Create(std::string deviceID, void* platformSpecific){
LOGW("in: PulseAudio available but not working; trying ALSA");
}
return new AudioInputALSA(deviceID);
+#elif defined(__HAIKU__)
+ return new AudioInputHaiku(deviceID);
#endif
}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioOutput.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioOutput.cpp
index 109d24d..c3cc014 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioOutput.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/audio/AudioOutput.cpp
@@ -25,6 +25,8 @@
#elif defined(__linux__)
#include "../os/linux/AudioOutputALSA.h"
#include "../os/linux/AudioOutputPulse.h"
+#elif defined(__HAIKU__)
+#include "../os/haiku/AudioOutputHaiku.h"
#else
#error "Unsupported operating system"
#endif
@@ -59,6 +61,9 @@ std::unique_ptr<AudioOutput> AudioOutput::Create(std::string deviceID, void* pla
LOGW("out: PulseAudio available but not working; trying ALSA");
}
return std::unique_ptr<AudioOutput>(new AudioOutputALSA(deviceID));
+#elif defined(__HAIKU__)
+ LOGW("out: MediaKitAudio enabled");
+ return std::unique_ptr<AudioOutput>(new AudioOutputHaiku(deviceID));
#endif
}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/libtgvoip.gyp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/libtgvoip.gyp
index f236987..24f017b 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/libtgvoip.gyp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/libtgvoip.gyp
@@ -100,6 +100,14 @@
'<(tgvoip_src_loc)/os/linux/PulseAudioLoader.cpp',
'<(tgvoip_src_loc)/os/linux/PulseAudioLoader.h',
+ # Haiku
+ '<(tgvoip_src_loc)/os/haiku/AudioInputHaiku.cpp',
+ '<(tgvoip_src_loc)/os/haiku/AudioInputHaiku.h',
+ '<(tgvoip_src_loc)/os/haiku/AudioOutputHaiku.cpp',
+ '<(tgvoip_src_loc)/os/haiku/AudioOutputHaiku.h',
+ '<(tgvoip_src_loc)/os/haiku/RingBuffer.cpp',
+ '<(tgvoip_src_loc)/os/haiku/RingBuffer.h',
+
# POSIX
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp',
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.h',
@@ -253,6 +261,11 @@
'sources/': [['exclude', '<(tgvoip_src_loc)/os/posix/']],
},
],
+ [
+ '"<(OS)" != "haiku"', {
+ 'sources/': [['exclude', '<(tgvoip_src_loc)/os/haiku/']],
+ },
+ ],
[
'"<(OS)" != "mac"', {
'sources/': [['exclude', '<(tgvoip_src_loc)/os/darwin/']],
@@ -378,6 +391,21 @@
},
],
[
+ '"<(OS)" == "haiku"', {
+ 'defines': [
+ 'WEBRTC_POSIX',
+ ],
+ 'cflags_cc': [
+ '-msse2',
+ '-std=gnu++14',
+ ],
+ 'direct_dependent_settings': {
+ 'libraries': [
+
+ ],
+ },
+ },
+ ], [
'"<(OS)" == "linux"', {
'defines': [
'WEBRTC_POSIX',
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp
new file mode 100644
index 0000000..ce54b6e
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp
@@ -0,0 +1,198 @@
+//
+// libtgvoip is free and unencumbered public domain software.
+// For more information, see http://unlicense.org or the UNLICENSE file
+// you should have received with this source code distribution.
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <dlfcn.h>
+#include "AudioInputHaiku.h"
+#include "../../logging.h"
+#include "../../VoIPController.h"
+
+#include "RingBuffer.h"
+
+#define BUFFER_SIZE 960
+
+using namespace tgvoip::audio;
+
+void RecordFile(void* cookie, bigtime_t timestamp, void* data, size_t size, const media_format &format)
+{
+ AudioInputHaiku *obj = (AudioInputHaiku*)cookie;
+ if (!obj->IsRecording())
+ return;
+ if (format.u.raw_audio.channel_count == 1) {
+ obj->fRingBuffer->Write((unsigned char*)data, size);
+ } else if (format.u.raw_audio.channel_count == 2) {
+ unsigned char *s = (unsigned char*)data;
+ for (int i=0; i<size/4; i++, s+=4)
+ obj->fRingBuffer->Write(s, 2);
+ }
+
+}
+
+void NotifyRecordFile(void * cookie, BMediaRecorder::notification code, ...)
+{
+ if (code == BMediaRecorder::B_WILL_STOP) {
+ }
+}
+
+AudioInputHaiku::AudioInputHaiku(std::string devID)
+{
+ fRecorder = NULL;
+ fRingBuffer = NULL;
+ isRecording = false;
+
+ status_t error;
+
+ fRoster = BMediaRoster::Roster(&error);
+ if (!fRoster) {
+ failed=true;
+ return;
+ }
+ error = fRoster->GetAudioInput(&fAudioInputNode);
+ if (error < B_OK) {
+ failed=true;
+ return;
+ }
+ error = fRoster->GetAudioMixer(&fAudioMixerNode);
+ if (error < B_OK) {
+ failed=true;
+ return;
+ }
+ fRecorder = new BMediaRecorder("Telegram", B_MEDIA_RAW_AUDIO);
+ if (fRecorder->InitCheck() < B_OK) {
+ failed=true;
+ return;
+ }
+ media_format output_format;
+ output_format.type = B_MEDIA_RAW_AUDIO;
+ output_format.u.raw_audio = media_raw_audio_format::wildcard;
+ output_format.u.raw_audio.channel_count = 1;
+ fRecorder->SetAcceptedFormat(output_format);
+
+ const int maxInputCount = 64;
+ dormant_node_info dni[maxInputCount];
+
+ int32 real_count = maxInputCount;
+
+ error = fRoster->GetDormantNodes(dni, &real_count, 0, &output_format, 0, B_BUFFER_PRODUCER | B_PHYSICAL_INPUT);
+ if (real_count > maxInputCount)
+ real_count = maxInputCount;
+ char selected_name[B_MEDIA_NAME_LENGTH] = "Default input";
+
+ for (int i = 0; i < real_count; i++) {
+ media_node_id ni[12];
+ int32 ni_count = 12;
+ error = fRoster->GetInstancesFor(dni[i].addon, dni[i].flavor_id, ni, &ni_count);
+ if (error == B_OK) {
+ for (int j = 0; j < ni_count; j++) {
+ if (ni[j] == fAudioInputNode.node) {
+ strcpy(selected_name, dni[i].name);
+ break;
+ }
+ }
+ }
+ }
+
+ media_output audioOutput;
+ if (!fRecorder->IsConnected()) {
+ int32 count = 0;
+ error = fRoster->GetFreeOutputsFor(fAudioInputNode, &audioOutput, 1, &count, B_MEDIA_RAW_AUDIO);
+ if (error < B_OK) {
+ failed=true;
+ return;
+ }
+
+ if (count < 1) {
+ failed=true;
+ return;
+ }
+ fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
+ } else {
+ fRecordFormat.u.raw_audio = fRecorder->AcceptedFormat().u.raw_audio;
+ }
+ fRecordFormat.type = B_MEDIA_RAW_AUDIO;
+
+ error = fRecorder->SetHooks(RecordFile, NotifyRecordFile, this);
+ if (error < B_OK) {
+ failed=true;
+ return;
+ }
+
+ if (!fRecorder->IsConnected()) {
+ error = fRecorder->Connect(fAudioInputNode, &audioOutput, &fRecordFormat);
+ if (error < B_OK) {
+ fRecorder->SetHooks(NULL, NULL, NULL);
+ failed=true;
+ return;
+ }
+ }
+
+ fRingBuffer = new RingBuffer(BUFFER_SIZE * 2 * 3);
+ if (fRingBuffer->InitCheck() != B_OK) {
+ failed=true;
+ return;
+ }
+}
+
+AudioInputHaiku::~AudioInputHaiku(){
+ if (fRecorder != NULL) {
+ if (fRecorder->InitCheck() == B_OK) {
+ if (fRecorder->IsConnected())
+ fRecorder->Disconnect();
+ }
+ delete fRecorder;
+ }
+ if (fRingBuffer != NULL)
+ delete fRingBuffer;
+}
+
+void AudioInputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
+
+}
+
+bool AudioInputHaiku::IsRecording(){
+ return isRecording;
+}
+
+void AudioInputHaiku::Start(){
+ if(failed || isRecording)
+ return;
+
+ isRecording=true;
+
+ thread = new Thread(new MethodPointer<AudioInputHaiku>(&AudioInputHaiku::RunThread, this), NULL);
+ thread->SetName("AudioInputHaiku");
+ thread->Start();
+
+ fRecorder->Start();
+}
+
+void AudioInputHaiku::Stop(){
+ if(!isRecording)
+ return;
+
+ isRecording=false;
+
+ fRecorder->Stop();
+
+ thread->Join();
+ delete thread;
+ thread=NULL;
+}
+
+void AudioInputHaiku::RunThread(void* arg){
+ unsigned char buffer[BUFFER_SIZE*2];
+ while (isRecording){
+ if (fRingBuffer->GetReadAvailable() >= sizeof(buffer)) {
+ int readed = fRingBuffer->Read(buffer, sizeof(buffer));
+ if (readed < sizeof(buffer))
+ memset(buffer + readed, 0, sizeof(buffer) - readed);
+ InvokeCallback(buffer, sizeof(buffer));
+ } else
+ snooze(100);
+ }
+}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h
new file mode 100644
index 0000000..80573df
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h
@@ -0,0 +1,57 @@
+//
+// libtgvoip is free and unencumbered public domain software.
+// For more information, see http://unlicense.org or the UNLICENSE file
+// you should have received with this source code distribution.
+//
+
+#ifndef LIBTGVOIP_AUDIOINPUTHAIKU_H
+#define LIBTGVOIP_AUDIOINPUTHAIKU_H
+
+#include "../../audio/AudioInput.h"
+#include "../../threading.h"
+
+#include <OS.h>
+#include <MediaFile.h>
+#include <MediaNode.h>
+#include <MediaRecorder.h>
+#include <MediaTrack.h>
+#include <MediaRoster.h>
+#include <TimeSource.h>
+#include <NodeInfo.h>
+#include <MediaAddOn.h>
+
+#include "RingBuffer.h"
+
+namespace tgvoip{
+namespace audio{
+
+class AudioInputHaiku : public AudioInput{
+
+public:
+ AudioInputHaiku(std::string devID);
+ virtual ~AudioInputHaiku();
+ virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
+ virtual void Start();
+ virtual void Stop();
+ virtual bool IsRecording();
+
+ RingBuffer *fRingBuffer;
+private:
+ void RunThread(void* arg);
+
+ bool isConfigured;
+ bool isRecording;
+
+ BMediaRoster * fRoster;
+ BMediaRecorder * fRecorder;
+ media_format fRecordFormat;
+ media_node fAudioInputNode;
+ media_node fAudioMixerNode;
+
+ Thread* thread;
+};
+
+}
+}
+
+#endif //LIBTGVOIP_AUDIOINPUTALSA_H
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp
new file mode 100644
index 0000000..4454323
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp
@@ -0,0 +1,101 @@
+//
+// libtgvoip is free and unencumbered public domain software.
+// For more information, see http://unlicense.org or the UNLICENSE file
+// you should have received with this source code distribution.
+//
+
+
+#include <assert.h>
+#include <dlfcn.h>
+#include "AudioOutputHaiku.h"
+#include "../../logging.h"
+#include "../../VoIPController.h"
+
+#define BUFFER_SIZE 960
+
+using namespace tgvoip::audio;
+
+static void playerProc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format)
+{
+ AudioOutputHaiku *obj = (AudioOutputHaiku*)cookie;
+ obj->InvokeCallback((unsigned char*)buffer, len);
+}
+
+
+AudioOutputHaiku::AudioOutputHaiku(std::string devID){
+ soundPlayer = NULL;
+ isPlaying = false;
+ isConfigured = false;
+ return;
+}
+
+AudioOutputHaiku::~AudioOutputHaiku(){
+ if (isConfigured) {
+ if (soundPlayer != NULL) {
+ soundPlayer->Stop();
+ delete soundPlayer;
+ }
+ }
+}
+
+void AudioOutputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
+ media_raw_audio_format mediaKitFormat = {
+ (float)sampleRate,
+ (uint32)channels,
+ media_raw_audio_format::B_AUDIO_SHORT,
+ B_MEDIA_LITTLE_ENDIAN,
+ (uint32)BUFFER_SIZE * 2 * channels
+ };
+
+ switch (bitsPerSample) {
+ case 8:
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_CHAR;
+ break;
+ case 16:
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ case 32:
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_INT;
+ break;
+ default:
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
+ break;
+ }
+
+ soundPlayer = new BSoundPlayer(&mediaKitFormat, "Telegram", playerProc, NULL, (void*)this);
+
+ if(soundPlayer->InitCheck() != B_OK) {
+ delete soundPlayer;
+ soundPlayer = NULL;
+ isPlaying = false;
+ return;
+ }
+
+ isConfigured = true;
+}
+
+void AudioOutputHaiku::Start(){
+ if(soundPlayer == NULL || isPlaying)
+ return;
+
+ soundPlayer->Start();
+ soundPlayer->SetHasData(true);
+
+ isPlaying=true;
+}
+
+void AudioOutputHaiku::Stop(){
+ if(!isPlaying)
+ return;
+
+ soundPlayer->Stop();
+ isPlaying=false;
+}
+
+bool AudioOutputHaiku::IsPlaying(){
+ return isPlaying;
+}
+
+float AudioOutputHaiku::GetLevel(){
+ return 0;
+}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h
new file mode 100644
index 0000000..6880709
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h
@@ -0,0 +1,36 @@
+//
+// libtgvoip is free and unencumbered public domain software.
+// For more information, see http://unlicense.org or the UNLICENSE file
+// you should have received with this source code distribution.
+//
+
+#ifndef LIBTGVOIP_AUDIOOUTPUTHAIKU_H
+#define LIBTGVOIP_AUDIOOUTPUTHAIKU_H
+
+#include "../../audio/AudioOutput.h"
+#include "../../threading.h"
+
+#include <SoundPlayer.h>
+
+namespace tgvoip{
+namespace audio{
+
+class AudioOutputHaiku : public AudioOutput{
+public:
+ AudioOutputHaiku(std::string devID);
+ virtual ~AudioOutputHaiku();
+ virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
+ virtual void Start();
+ virtual void Stop();
+ virtual bool IsPlaying() override;
+ virtual float GetLevel() override;
+private:
+ bool isPlaying;
+ bool isConfigured;
+ BSoundPlayer *soundPlayer;
+};
+
+}
+}
+
+#endif //LIBTGVOIP_AudioOutputHaiku_H
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.cpp
new file mode 100644
index 0000000..43236d3
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.cpp
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <OS.h>
+
+#include "RingBuffer.h"
+
+RingBuffer::RingBuffer( int size )
+{
+ initialized = false;
+ Buffer = new unsigned char[size];
+ if(Buffer!=NULL) {
+ memset( Buffer, 0, size );
+ BufferSize = size;
+ } else {
+ BufferSize = 0;
+ }
+ reader = 0;
+ writer = 0;
+ writeBytesAvailable = size;
+ if((locker=create_sem(1,"locker")) >= B_OK) {
+ initialized = true;
+ } else {
+ if(Buffer!=NULL) {
+ delete[] Buffer;
+ }
+ }
+}
+
+RingBuffer::~RingBuffer( )
+{
+ if(initialized) {
+ delete[] Buffer;
+ delete_sem(locker);
+ }
+}
+
+bool
+RingBuffer::Empty( void )
+{
+ memset( Buffer, 0, BufferSize );
+ reader = 0;
+ writer = 0;
+ writeBytesAvailable = BufferSize;
+ return true;
+}
+
+int
+RingBuffer::Read( unsigned char *data, int size )
+{
+ acquire_sem(locker);
+
+ if( data == 0 || size <= 0 || writeBytesAvailable == BufferSize ) {
+ release_sem(locker);
+ return 0;
+ }
+
+ int readBytesAvailable = BufferSize - writeBytesAvailable;
+
+ if( size > readBytesAvailable ) {
+ size = readBytesAvailable;
+ }
+
+ if(size > BufferSize - reader) {
+ int len = BufferSize - reader;
+ memcpy(data, Buffer + reader, len);
+ memcpy(data + len, Buffer, size-len);
+ } else {
+ memcpy(data, Buffer + reader, size);
+ }
+
+ reader = (reader + size) % BufferSize;
+ writeBytesAvailable += size;
+
+ release_sem(locker);
+ return size;
+}
+
+int
+RingBuffer::Write( unsigned char *data, int size )
+{
+ acquire_sem(locker);
+
+ if( data == 0 || size <= 0 || writeBytesAvailable == 0 ) {
+ release_sem(locker);
+ return 0;
+ }
+
+ if( size > writeBytesAvailable ) {
+ size = writeBytesAvailable;
+ }
+
+ if(size > BufferSize - writer) {
+ int len = BufferSize - writer;
+ memcpy(Buffer + writer, data, len);
+ memcpy(Buffer, data+len, size-len);
+ } else {
+ memcpy(Buffer + writer, data, size);
+ }
+
+ writer = (writer + size) % BufferSize;
+ writeBytesAvailable -= size;
+
+ release_sem(locker);
+ return size;
+}
+
+int
+RingBuffer::GetSize( void )
+{
+ return BufferSize;
+}
+
+int
+RingBuffer::GetWriteAvailable( void )
+{
+ return writeBytesAvailable;
+}
+
+int
+RingBuffer::GetReadAvailable( void )
+{
+ return BufferSize - writeBytesAvailable;
+}
+
+status_t
+RingBuffer::InitCheck( void )
+{
+ return initialized?B_OK:B_ERROR;
+}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.h
new file mode 100644
index 0000000..4715632
--- /dev/null
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/RingBuffer.h
@@ -0,0 +1,31 @@
+#ifndef __RING_BUFFER_H__
+#define __RING_BUFFER_H__
+
+#include <OS.h>
+
+class RingBuffer {
+
+public:
+ RingBuffer(int size);
+ ~RingBuffer();
+ int Read( unsigned char* dataPtr, int numBytes );
+ int Write( unsigned char *dataPtr, int numBytes );
+
+ bool Empty( void );
+ int GetSize( );
+ int GetWriteAvailable( );
+ int GetReadAvailable( );
+ status_t InitCheck( );
+private:
+ unsigned char *Buffer;
+ int BufferSize;
+ int reader;
+ int writer;
+ int writeBytesAvailable;
+
+ sem_id locker;
+
+ bool initialized;
+};
+
+#endif
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/posix/NetworkSocketPosix.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/posix/NetworkSocketPosix.cpp
index 05ddbb9..fcf7580 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/posix/NetworkSocketPosix.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/posix/NetworkSocketPosix.cpp
@@ -47,6 +47,7 @@ NetworkSocketPosix::~NetworkSocketPosix(){
}
void NetworkSocketPosix::SetMaxPriority(){
+#ifndef __HAIKU__
#ifdef __APPLE__
int prio=NET_SERVICE_TYPE_VO;
int res=setsockopt(fd, SOL_SOCKET, SO_NET_SERVICE_TYPE, &prio, sizeof(prio));
@@ -65,6 +66,7 @@ void NetworkSocketPosix::SetMaxPriority(){
LOGE("error setting ip tos: %d / %s", errno, strerror(errno));
}
#endif
+#endif //__HAIKU__
}
void NetworkSocketPosix::Send(NetworkPacket *packet){
@@ -196,8 +198,10 @@ void NetworkSocketPosix::Open(){
int res=setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag));
if(res<0){
LOGE("error enabling dual stack socket: %d / %s", errno, strerror(errno));
+#ifndef __HAIKU__
failed=true;
return;
+#endif
}
SetMaxPriority();
@@ -345,6 +349,8 @@ std::string NetworkSocketPosix::GetLocalInterfaceInfo(IPv4Address *v4addr, IPv6A
if(didAttach){
sharedJVM->DetachCurrentThread();
}
+#elif defined(__HAIKU__)
+ return name;
#else
struct ifaddrs* interfaces;
if(!getifaddrs(&interfaces)){
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/threading.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/threading.h
index 0b4933c..87ea3b7 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/threading.h
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/threading.h
@@ -33,7 +33,7 @@ namespace tgvoip{
};
}
-#if defined(_POSIX_THREADS) || defined(_POSIX_VERSION) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
+#if defined(_POSIX_THREADS) || defined(_POSIX_VERSION) || defined(__unix__) || defined(__unix) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__))
#include <pthread.h>
#include <semaphore.h>
@@ -94,11 +94,13 @@ namespace tgvoip{
static void* ActualEntryPoint(void* arg){
Thread* self=reinterpret_cast<Thread*>(arg);
if(self->name){
+#ifndef __HAIKU__
#ifndef __APPLE__
pthread_setname_np(self->thread, self->name);
#else
pthread_setname_np(self->name);
#endif
+#endif //__HAKIU__
}
self->entry->Invoke(self->arg);
return NULL;
--
2.16.4
From 4dbfc02248dde7ae10d29d81f25575942f204c89 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 10 Jun 2018 22:01:28 +1000
Subject: Add mix and resample for haiku audio input
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp
index ce54b6e..d7cc39a 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.cpp
@@ -10,32 +10,104 @@
#include <dlfcn.h>
#include "AudioInputHaiku.h"
#include "../../logging.h"
+#include "../../audio/Resampler.h"
#include "../../VoIPController.h"
#include "RingBuffer.h"
-#define BUFFER_SIZE 960
-
using namespace tgvoip::audio;
-void RecordFile(void* cookie, bigtime_t timestamp, void* data, size_t size, const media_format &format)
+void RecordData(void* cookie, bigtime_t timestamp, void* data, size_t size, const media_format &format)
{
- AudioInputHaiku *obj = (AudioInputHaiku*)cookie;
- if (!obj->IsRecording())
+ AudioInputHaiku *audioInput = (AudioInputHaiku*)cookie;
+ if (!audioInput->IsRecording())
+ return;
+
+ if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_SHORT &&
+ format.u.raw_audio.channel_count == 1) {
+ audioInput->fRingBuffer->Write((unsigned char*)data, size);
return;
- if (format.u.raw_audio.channel_count == 1) {
- obj->fRingBuffer->Write((unsigned char*)data, size);
- } else if (format.u.raw_audio.channel_count == 2) {
- unsigned char *s = (unsigned char*)data;
- for (int i=0; i<size/4; i++, s+=4)
- obj->fRingBuffer->Write(s, 2);
}
-
+
+ uint32 bytesPerSample = 2;
+ switch (format.u.raw_audio.format) {
+ case media_raw_audio_format::B_AUDIO_CHAR:
+ bytesPerSample = 1;
+ break;
+ case media_raw_audio_format::B_AUDIO_SHORT:
+ bytesPerSample = 2;
+ break;
+ case media_raw_audio_format::B_AUDIO_INT:
+ bytesPerSample = 4;
+ break;
+ case media_raw_audio_format::B_AUDIO_FLOAT:
+ bytesPerSample = 4;
+ break;
+ default:
+ break;
+ }
+
+ int frames = size / (format.u.raw_audio.channel_count * bytesPerSample);
+ int16_t *dst = audioInput->workBuffer;
+
+ if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_CHAR) {
+ unsigned char* src=reinterpret_cast<unsigned char*>(data);
+ for (int n=0; n < frames; n++) {
+ int32_t value = 0;
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
+ value += ((int32_t)(*src) - INT8_MAX) * UINT8_MAX;
+ }
+ value /= format.u.raw_audio.channel_count;
+ dst[n] = (int16_t)value;
+ }
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_SHORT) {
+ int16_t* src=reinterpret_cast<int16_t*>(data);
+ for (int n=0; n < frames; n++) {
+ int32_t value = 0;
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
+ value += *src;
+ }
+ value /= format.u.raw_audio.channel_count;
+ dst[n] = (int16_t)value;
+ }
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_INT) {
+ int32_t* src=reinterpret_cast<int32_t*>(data);
+ for (int n=0; n < frames; n++) {
+ int64_t value = 0;
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
+ value += (int64_t)(*src);
+ }
+ value /= format.u.raw_audio.channel_count;
+ dst[n] = (int16_t)(value / (UINT16_MAX + 1));
+ }
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_FLOAT) {
+ float* src=reinterpret_cast<float*>(data);
+ for (int n=0; n < frames; n++) {
+ float value = 0;
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
+ value += *src;
+ }
+ value /= format.u.raw_audio.channel_count;
+ dst[n] = (int16_t)(value*INT16_MAX);
+ }
+ }
+
+ if(format.u.raw_audio.frame_rate != audioInput->tgFrameRate) {
+ size_t len = tgvoip::audio::Resampler::Convert(dst, audioInput->convertBuffer,
+ frames, frames, audioInput->tgFrameRate, format.u.raw_audio.frame_rate) * audioInput->tgBytesPerSample;
+ audioInput->fRingBuffer->Write((unsigned char*)audioInput->convertBuffer, len);
+ } else {
+ audioInput->fRingBuffer->Write((unsigned char*)dst, frames * audioInput->tgBytesPerSample);
+ }
}
-void NotifyRecordFile(void * cookie, BMediaRecorder::notification code, ...)
+void NotifyRecordData(void * cookie, BMediaRecorder::notification code, ...)
{
+ AudioInputHaiku *audioInput = (AudioInputHaiku*)cookie;
if (code == BMediaRecorder::B_WILL_STOP) {
+ if (audioInput->IsRecording()) {
+ audioInput->Stop();
+ }
}
}
@@ -116,7 +188,7 @@ AudioInputHaiku::AudioInputHaiku(std::string devID)
}
fRecordFormat.type = B_MEDIA_RAW_AUDIO;
- error = fRecorder->SetHooks(RecordFile, NotifyRecordFile, this);
+ error = fRecorder->SetHooks(RecordData, NotifyRecordData, this);
if (error < B_OK) {
failed=true;
return;
@@ -151,7 +223,9 @@ AudioInputHaiku::~AudioInputHaiku(){
}
void AudioInputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
-
+ tgFrameRate = sampleRate;
+ tgChannelsCount = channels;
+ tgBytesPerSample = bitsPerSample / 8;
}
bool AudioInputHaiku::IsRecording(){
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h
index 80573df..746d7df 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioInputHaiku.h
@@ -22,6 +22,8 @@
#include "RingBuffer.h"
+#define BUFFER_SIZE 960
+
namespace tgvoip{
namespace audio{
@@ -34,8 +36,15 @@ public:
virtual void Start();
virtual void Stop();
virtual bool IsRecording();
-
- RingBuffer *fRingBuffer;
+
+ RingBuffer *fRingBuffer;
+ int16_t workBuffer[BUFFER_SIZE * 16];
+ int16_t convertBuffer[BUFFER_SIZE * 16];
+
+ uint32 tgFrameRate;
+ uint32 tgChannelsCount;
+ uint32 tgBytesPerSample;
+
private:
void RunThread(void* arg);
@@ -47,11 +56,11 @@ private:
media_format fRecordFormat;
media_node fAudioInputNode;
media_node fAudioMixerNode;
-
+
Thread* thread;
};
}
}
-#endif //LIBTGVOIP_AUDIOINPUTALSA_H
+#endif //LIBTGVOIP_AUDIOINPUTHAIKU_H
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp
index 4454323..11650da 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.cpp
@@ -44,7 +44,7 @@ void AudioOutputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, ui
(uint32)channels,
media_raw_audio_format::B_AUDIO_SHORT,
B_MEDIA_LITTLE_ENDIAN,
- (uint32)BUFFER_SIZE * 2 * channels
+ (uint32)BUFFER_SIZE * (bitsPerSample / 8) * channels
};
switch (bitsPerSample) {
@@ -68,6 +68,7 @@ void AudioOutputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, ui
delete soundPlayer;
soundPlayer = NULL;
isPlaying = false;
+ failed = true;
return;
}
diff --git a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h
index 6880709..6a463fa 100644
--- a/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h
+++ b/libtgvoip-6ba1241cfef6c3ddf4e50e82f67afde0abc02285/os/haiku/AudioOutputHaiku.h
@@ -33,4 +33,4 @@ private:
}
}
-#endif //LIBTGVOIP_AudioOutputHaiku_H
+#endif //LIBTGVOIP_AUDIOOUTPUTHAIKU_H
--
2.16.4