mirror of
https://github.com/yann64/haikuports.git
synced 2026-05-03 13:38:52 +02:00
965 lines
28 KiB
Plaintext
965 lines
28 KiB
Plaintext
From ad449f133830076fad26121a34d780a0c385ce25 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Sat, 10 Aug 2019 12:20:44 +1000
|
|
Subject: Add mediakit support
|
|
|
|
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp
|
|
old mode 100755
|
|
new mode 100644
|
|
index 0ecd63e..61081f9
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp
|
|
@@ -10,7 +10,7 @@
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <algorithm>
|
|
-#ifdef HAVE_CONFIG_H
|
|
+#if defined(HAVE_CONFIG_H) || defined(__HAIKU__)
|
|
#include <opus/opus.h>
|
|
#else
|
|
#include "opus.h"
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp
|
|
old mode 100755
|
|
new mode 100644
|
|
index 8786bf5..ab5abc4
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp
|
|
@@ -9,7 +9,7 @@
|
|
#include <algorithm>
|
|
#include "logging.h"
|
|
#include "VoIPServerConfig.h"
|
|
-#ifdef HAVE_CONFIG_H
|
|
+#if defined(HAVE_CONFIG_H) || defined(__HAIKU__)
|
|
#include <opus/opus.h>
|
|
#else
|
|
#include "opus.h"
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.h
|
|
old mode 100755
|
|
new mode 100644
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp
|
|
old mode 100755
|
|
new mode 100644
|
|
index d9297ce..ca81e70
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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>
|
|
@@ -3052,6 +3055,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-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp
|
|
index 2c16ca7..e00c731 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp
|
|
@@ -39,6 +39,9 @@
|
|
#ifndef WITHOUT_PULSE
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioInputHaiku.h"
|
|
+#include "../os/haiku/AudioOutputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
@@ -65,6 +68,8 @@ AudioIO* AudioIO::Create(std::string inputDevice, std::string outputDevice){
|
|
return new ContextlessAudioIO<AudioInputWave, AudioOutputWave>(inputDevice, outputDevice);
|
|
#endif
|
|
return new ContextlessAudioIO<AudioInputWASAPI, AudioOutputWASAPI>(inputDevice, outputDevice);
|
|
+#elif defined(__HAIKU__)
|
|
+ return new ContextlessAudioIO<AudioInputHaiku, AudioOutputHaiku>();
|
|
#elif defined(__linux__)
|
|
#ifndef WITHOUT_ALSA
|
|
#ifndef WITHOUT_PULSE
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp
|
|
index dae647a..4bab98c 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp
|
|
@@ -33,6 +33,8 @@
|
|
#ifndef WITHOUT_PULSE
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioInputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp
|
|
index 458e8a5..1890350 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp
|
|
@@ -37,6 +37,8 @@
|
|
#include "../os/linux/AudioOutputPulse.h"
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioOutputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp
|
|
index b5f3b81..1d5b508 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp
|
|
@@ -115,6 +115,14 @@
|
|
'<(tgvoip_src_loc)/os/linux/AudioPulse.cpp',
|
|
'<(tgvoip_src_loc)/os/linux/AudioPulse.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',
|
|
@@ -737,6 +745,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/']],
|
|
@@ -895,6 +908,22 @@
|
|
},
|
|
],
|
|
[
|
|
+ '"<(OS)" == "haiku"', {
|
|
+ 'defines': [
|
|
+ 'WEBRTC_POSIX',
|
|
+ 'WEBRTC_HAIKU',
|
|
+ ],
|
|
+ 'cflags_cc': [
|
|
+ '-msse2',
|
|
+ '-std=gnu++14',
|
|
+ ],
|
|
+ 'direct_dependent_settings': {
|
|
+ 'libraries': [
|
|
+
|
|
+ ],
|
|
+ },
|
|
+ },
|
|
+ ], [
|
|
'"<(OS)" == "linux"', {
|
|
'defines': [
|
|
'WEBRTC_POSIX',
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.cpp
|
|
new file mode 100644
|
|
index 0000000..7cce3e3
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.cpp
|
|
@@ -0,0 +1,276 @@
|
|
+//
|
|
+// 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 "../../audio/Resampler.h"
|
|
+#include "../../VoIPController.h"
|
|
+
|
|
+#include "RingBuffer.h"
|
|
+
|
|
+using namespace tgvoip::audio;
|
|
+
|
|
+void RecordData(void* cookie, bigtime_t timestamp, void* data, size_t size, const media_format &format)
|
|
+{
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ 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 NotifyRecordData(void * cookie, BMediaRecorder::notification code, ...)
|
|
+{
|
|
+ AudioInputHaiku *audioInput = (AudioInputHaiku*)cookie;
|
|
+ if (code == BMediaRecorder::B_WILL_STOP) {
|
|
+ if (audioInput->IsRecording()) {
|
|
+ audioInput->Stop();
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+AudioInputHaiku::AudioInputHaiku()
|
|
+{
|
|
+ fRecorder = NULL;
|
|
+ fRingBuffer = NULL;
|
|
+ isRecording = false;
|
|
+
|
|
+ tgFrameRate = 48000;
|
|
+ tgChannelsCount = 1;
|
|
+ tgBytesPerSample = 2;
|
|
+
|
|
+ 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(RecordData, NotifyRecordData, 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){
|
|
+ tgFrameRate = sampleRate;
|
|
+ tgChannelsCount = channels;
|
|
+ tgBytesPerSample = bitsPerSample / 8;
|
|
+}
|
|
+
|
|
+bool AudioInputHaiku::IsRecording(){
|
|
+ return isRecording;
|
|
+}
|
|
+
|
|
+void AudioInputHaiku::Start(){
|
|
+ if(failed || isRecording)
|
|
+ return;
|
|
+
|
|
+ isRecording=true;
|
|
+
|
|
+ thread = new Thread(std::bind(&AudioInputHaiku::RunThread, this));
|
|
+ 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(){
|
|
+ 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-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.h
|
|
new file mode 100644
|
|
index 0000000..1c63afe
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.h
|
|
@@ -0,0 +1,66 @@
|
|
+//
|
|
+// 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"
|
|
+
|
|
+#define BUFFER_SIZE 960
|
|
+
|
|
+namespace tgvoip{
|
|
+namespace audio{
|
|
+
|
|
+class AudioInputHaiku : public AudioInput{
|
|
+
|
|
+public:
|
|
+ AudioInputHaiku();
|
|
+ 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;
|
|
+ int16_t workBuffer[BUFFER_SIZE * 64];
|
|
+ int16_t convertBuffer[BUFFER_SIZE * 64];
|
|
+
|
|
+ uint32 tgFrameRate;
|
|
+ uint32 tgChannelsCount;
|
|
+ uint32 tgBytesPerSample;
|
|
+
|
|
+private:
|
|
+ void RunThread();
|
|
+
|
|
+ bool isConfigured;
|
|
+ bool isRecording;
|
|
+
|
|
+ BMediaRoster * fRoster;
|
|
+ BMediaRecorder * fRecorder;
|
|
+ media_format fRecordFormat;
|
|
+ media_node fAudioInputNode;
|
|
+ media_node fAudioMixerNode;
|
|
+
|
|
+ Thread* thread;
|
|
+};
|
|
+
|
|
+}
|
|
+}
|
|
+
|
|
+#endif //LIBTGVOIP_AUDIOINPUTHAIKU_H
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.cpp
|
|
new file mode 100644
|
|
index 0000000..2fca8a1
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.cpp
|
|
@@ -0,0 +1,99 @@
|
|
+//
|
|
+// 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(){
|
|
+ soundPlayer = NULL;
|
|
+ isPlaying = false;
|
|
+ isConfigured = false;
|
|
+ Configure(48000, 16, 1);
|
|
+ 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 * (bitsPerSample / 8) * 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;
|
|
+ failed = true;
|
|
+ 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;
|
|
+}
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.h
|
|
new file mode 100644
|
|
index 0000000..91f2521
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.h
|
|
@@ -0,0 +1,35 @@
|
|
+//
|
|
+// 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();
|
|
+ virtual ~AudioOutputHaiku();
|
|
+ virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
+ virtual void Start();
|
|
+ virtual void Stop();
|
|
+ virtual bool IsPlaying() override;
|
|
+private:
|
|
+ bool isPlaying;
|
|
+ bool isConfigured;
|
|
+ BSoundPlayer *soundPlayer;
|
|
+};
|
|
+
|
|
+}
|
|
+}
|
|
+
|
|
+#endif //LIBTGVOIP_AUDIOOUTPUTHAIKU_H
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.cpp
|
|
new file mode 100644
|
|
index 0000000..43236d3
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.h
|
|
new file mode 100644
|
|
index 0000000..4715632
|
|
--- /dev/null
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp
|
|
index 52eef76..c480dfb 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp
|
|
@@ -248,12 +248,13 @@ void NetworkSocketPosix::Open(){
|
|
}
|
|
int flag=0;
|
|
int res=setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag));
|
|
+#ifndef __HAIKU__
|
|
if(res<0){
|
|
LOGE("error enabling dual stack socket: %d / %s", errno, strerror(errno));
|
|
failed=true;
|
|
return;
|
|
}
|
|
-
|
|
+#endif
|
|
SetMaxPriority();
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
|
|
@@ -403,6 +404,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-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h
|
|
old mode 100755
|
|
new mode 100644
|
|
index 9dc2554..fc68fd4
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h
|
|
@@ -9,7 +9,7 @@
|
|
|
|
#include <functional>
|
|
|
|
-#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>
|
|
@@ -92,6 +92,7 @@ namespace tgvoip{
|
|
static void* ActualEntryPoint(void* arg){
|
|
Thread* self=reinterpret_cast<Thread*>(arg);
|
|
if(self->name){
|
|
+#ifndef __HAIKU__
|
|
#if !defined(__APPLE__) && !defined(__gnu_hurd__)
|
|
pthread_setname_np(self->thread, self->name);
|
|
#elif !defined(__gnu_hurd__)
|
|
@@ -100,6 +101,7 @@ namespace tgvoip{
|
|
DarwinSpecific::SetCurrentThreadPriority(DarwinSpecific::THREAD_PRIO_USER_INTERACTIVE);
|
|
}
|
|
#endif
|
|
+#endif //__HAIKU__
|
|
}
|
|
self->entry();
|
|
return NULL;
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
old mode 100755
|
|
new mode 100644
|
|
index a8d1522..991241b
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
@@ -28,6 +28,10 @@
|
|
static const int kMaxLogLineSize = 1024 - 60;
|
|
#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID
|
|
|
|
+#if defined(WEBRTC_HAIKU)
|
|
+#include <OS.h>
|
|
+#endif
|
|
+
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
@@ -120,7 +124,12 @@ LogMessage::LogMessage(const char* file,
|
|
|
|
if (thread_) {
|
|
PlatformThreadId id = CurrentThreadId();
|
|
+#if defined(WEBRTC_HAIKU)
|
|
+ thread_id tid = get_pthread_thread_id(id);
|
|
+ print_stream_ << "[" << tid << "] ";
|
|
+#else
|
|
print_stream_ << "[" << id << "] ";
|
|
+#endif
|
|
}
|
|
|
|
if (file != nullptr) {
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_file.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_file.h
|
|
old mode 100755
|
|
new mode 100644
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
index 70cf237..e48948e 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
@@ -20,6 +20,8 @@ namespace rtc {
|
|
PlatformThreadId CurrentThreadId() {
|
|
#if defined(WEBRTC_WIN)
|
|
return GetCurrentThreadId();
|
|
+#elif defined(WEBRTC_HAIKU)
|
|
+ return pthread_self();
|
|
#elif defined(WEBRTC_POSIX)
|
|
#if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
|
|
return pthread_mach_thread_np(pthread_self());
|
|
diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
index 0bc42eb..c87cde9 100644
|
|
--- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
@@ -35,6 +35,9 @@ typedef DWORD PlatformThreadRef;
|
|
#elif defined(WEBRTC_FUCHSIA)
|
|
typedef zx_handle_t PlatformThreadId;
|
|
typedef zx_handle_t PlatformThreadRef;
|
|
+#elif defined(WEBRTC_HAIKU)
|
|
+typedef pthread_t PlatformThreadId;
|
|
+typedef pthread_t PlatformThreadRef;
|
|
#elif defined(WEBRTC_POSIX)
|
|
typedef pid_t PlatformThreadId;
|
|
typedef pthread_t PlatformThreadRef;
|
|
--
|
|
2.21.0
|
|
|