diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..3f550c73
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libs/oboe"]
+ path = libs/oboe
+ url = https://github.com/google/oboe.git
diff --git a/ChangeLog b/ChangeLog
index fdd8fe30..06f7c09b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,7 +7,7 @@
- for CoreAudio and 4 channel input, support mixing channels 1&2 with 3&4
-- added bassoon/oboe/harp instrument icons created by dszgit; congas created by bspeer (Ticket #131)
+- added bassoon/oboe/harp instrument icons created by dszgit; congas/bongo created by bspeer (Ticket #131)
- link to docs from application Help menu (Ticket #90)
@@ -24,6 +24,8 @@
TODO WIP support internationalization
+TODO improve disconnect message behaviour on client
+
TODO implement panning for channels (Ticket #52, #145)
TODO show mute state of others
diff --git a/Jamulus.pro b/Jamulus.pro
index b517c99b..4ba4813a 100755
--- a/Jamulus.pro
+++ b/Jamulus.pro
@@ -128,11 +128,138 @@ win32 {
LIBS += /usr/local/lib/libjack.dylib
}
} else:android {
+ # we want to compile with C++14
+ CONFIG += c++14
+
+ QT += androidextras
+
+ # enabled only for debugging on android devices
+ DEFINES += ANDROIDDEBUG
+
+ target.path = /tmp/your_executable # path on device
+ INSTALLS += target
+
HEADERS += android/sound.h
- SOURCES += android/sound.cpp
+ SOURCES += android/sound.cpp \
+ android/androiddebug.cpp
+
LIBS += -lOpenSLES
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/AndroidManifest.xml
+
+# if compiling for android you need to use Oboe library which is included as a git submodule
+# make sure you git pull with submodules to pull the latest Oboe library
+OBOE_SOURCES = libs/oboe/src/aaudio/AAudioLoader.cpp \
+ libs/oboe/src/aaudio/AudioStreamAAudio.cpp \
+ libs/oboe/src/common/AudioSourceCaller.cpp \
+ libs/oboe/src/common/AudioStream.cpp \
+ libs/oboe/src/common/AudioStreamBuilder.cpp \
+ libs/oboe/src/common/DataConversionFlowGraph.cpp \
+ libs/oboe/src/common/FilterAudioStream.cpp \
+ libs/oboe/src/common/FixedBlockAdapter.cpp \
+ libs/oboe/src/common/FixedBlockReader.cpp \
+ libs/oboe/src/common/FixedBlockWriter.cpp \
+ libs/oboe/src/common/LatencyTuner.cpp \
+ libs/oboe/src/common/QuirksManager.cpp \
+ libs/oboe/src/common/SourceFloatCaller.cpp \
+ libs/oboe/src/common/SourceI16Caller.cpp \
+ libs/oboe/src/common/StabilizedCallback.cpp \
+ libs/oboe/src/common/Trace.cpp \
+ libs/oboe/src/common/Utilities.cpp \
+ libs/oboe/src/common/Version.cpp \
+ libs/oboe/src/fifo/FifoBuffer.cpp \
+ libs/oboe/src/fifo/FifoController.cpp \
+ libs/oboe/src/fifo/FifoControllerBase.cpp \
+ libs/oboe/src/fifo/FifoControllerIndirect.cpp \
+ libs/oboe/src/flowgraph/ClipToRange.cpp \
+ libs/oboe/src/flowgraph/FlowGraphNode.cpp \
+ libs/oboe/src/flowgraph/ManyToMultiConverter.cpp \
+ libs/oboe/src/flowgraph/MonoToMultiConverter.cpp \
+ libs/oboe/src/flowgraph/RampLinear.cpp \
+ libs/oboe/src/flowgraph/SampleRateConverter.cpp \
+ libs/oboe/src/flowgraph/SinkFloat.cpp \
+ libs/oboe/src/flowgraph/SinkI16.cpp \
+ libs/oboe/src/flowgraph/SinkI24.cpp \
+ libs/oboe/src/flowgraph/SourceFloat.cpp \
+ libs/oboe/src/flowgraph/SourceI16.cpp \
+ libs/oboe/src/flowgraph/SourceI24.cpp \
+ libs/oboe/src/flowgraph/resampler/IntegerRatio.cpp \
+ libs/oboe/src/flowgraph/resampler/LinearResampler.cpp \
+ libs/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp \
+ libs/oboe/src/flowgraph/resampler/SincResampler.cpp \
+ libs/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp \
+ libs/oboe/src/opensles/AudioInputStreamOpenSLES.cpp \
+ libs/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp \
+ libs/oboe/src/opensles/AudioStreamBuffered.cpp \
+ libs/oboe/src/opensles/AudioStreamOpenSLES.cpp \
+ libs/oboe/src/opensles/EngineOpenSLES.cpp \
+ libs/oboe/src/opensles/OpenSLESUtilities.cpp \
+ libs/oboe/src/opensles/OutputMixerOpenSLES.cpp
+
+OBOE_HEADERS = libs/oboe/src/aaudio/AAudioLoader.h \
+ libs/oboe/src/aaudio/AudioStreamAAudio.h \
+ libs/oboe/src/common/AudioClock.h \
+ libs/oboe/src/common/AudioSourceCaller.h \
+ libs/oboe/src/common/DataConversionFlowGraph.h \
+ libs/oboe/src/common/FilterAudioStream.h \
+ libs/oboe/src/common/FixedBlockAdapter.h \
+ libs/oboe/src/common/FixedBlockReader.h \
+ libs/oboe/src/common/FixedBlockWriter.h \
+ libs/oboe/src/common/MonotonicCounter.h \
+ libs/oboe/src/common/OboeDebug.h \
+ libs/oboe/src/common/QuirksManager.h \
+ libs/oboe/src/common/SourceFloatCaller.h \
+ libs/oboe/src/common/SourceI16Caller.h \
+ libs/oboe/src/common/Trace.h \
+ libs/oboe/src/fifo/FifoBuffer.h \
+ libs/oboe/src/fifo/FifoController.h \
+ libs/oboe/src/fifo/FifoControllerBase.h \
+ libs/oboe/src/fifo/FifoControllerIndirect.h \
+ libs/oboe/src/flowgraph/ClipToRange.h \
+ libs/oboe/src/flowgraph/FlowGraphNode.h \
+ libs/oboe/src/flowgraph/ManyToMultiConverter.h \
+ libs/oboe/src/flowgraph/MonoToMultiConverter.h \
+ libs/oboe/src/flowgraph/RampLinear.h \
+ libs/oboe/src/flowgraph/SampleRateConverter.h \
+ libs/oboe/src/flowgraph/SinkFloat.h \
+ libs/oboe/src/flowgraph/SinkI16.h \
+ libs/oboe/src/flowgraph/SinkI24.h \
+ libs/oboe/src/flowgraph/SourceFloat.h \
+ libs/oboe/src/flowgraph/SourceI16.h \
+ libs/oboe/src/flowgraph/SourceI24.h \
+ libs/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h \
+ libs/oboe/src/flowgraph/resampler/IntegerRatio.h \
+ libs/oboe/src/flowgraph/resampler/LinearResampler.h \
+ libs/oboe/src/flowgraph/resampler/MultiChannelResampler.h \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResampler.h \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h \
+ libs/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h \
+ libs/oboe/src/flowgraph/resampler/SincResampler.h \
+ libs/oboe/src/flowgraph/resampler/SincResamplerStereo.h \
+ libs/oboe/src/opensles/AudioInputStreamOpenSLES.h \
+ libs/oboe/src/opensles/AudioOutputStreamOpenSLES.h \
+ libs/oboe/src/opensles/AudioStreamBuffered.h \
+ libs/oboe/src/opensles/AudioStreamOpenSLES.h \
+ libs/oboe/src/opensles/EngineOpenSLES.h \
+ libs/oboe/src/opensles/OpenSLESUtilities.h \
+ libs/oboe/src/opensles/OutputMixerOpenSLES.h
+
+INCLUDEPATH_OBOE = libs/oboe/include/ \
+ libs/oboe/src/
+
+DISTFILES_OBOE += libs/oboe/AUTHORS \
+ libs/oboe/CONTRIBUTING \
+ libs/oboe/LICENSE \
+ libs/oboe/README
+
+ INCLUDEPATH += $$INCLUDEPATH_OBOE
+ HEADERS += $$OBOE_HEADERS
+ SOURCES += $$OBOE_SOURCES
+ DISTFILES += $$DISTFILES_OBOE
+
} else:unix {
# we want to compile with C++11
QMAKE_CXXFLAGS += -std=c++11
@@ -492,6 +619,12 @@ DISTFILES += ChangeLog \
COPYING \
INSTALL.md \
README.md \
+ android/build.gradle \
+ android/gradle/wrapper/gradle-wrapper.jar \
+ android/gradle/wrapper/gradle-wrapper.properties \
+ android/gradlew \
+ android/gradlew.bat \
+ android/res/values/libs.xml \
src/res/CLEDBlack.png \
src/res/CLEDBlackSmall.png \
src/res/CLEDDisabledSmall.png \
@@ -581,6 +714,8 @@ DISTFILES += ChangeLog \
src/res/instruments/viola.png \
src/res/instruments/congas.svg \
src/res/instruments/congas.png \
+ src/res/instruments/bongo.svg \
+ src/res/instruments/bongo.png \
src/res/flags/flagnone.png \
src/res/flags/ad.png \
src/res/flags/ae.png \
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index addcb052..cba6d9a2 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -1,41 +1,94 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
diff --git a/android/androiddebug.cpp b/android/androiddebug.cpp
new file mode 100644
index 00000000..93656a47
--- /dev/null
+++ b/android/androiddebug.cpp
@@ -0,0 +1,45 @@
+const char*const applicationName="Jamulus";
+
+#ifdef ANDROIDDEBUG // Set in my myapp.pro file for android builds
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void myMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
+{
+ QString report=msg;
+ if (context.file && !QString(context.file).isEmpty()) {
+ report+=" in file ";
+ report+=QString(context.file);
+ report+=" line ";
+ report+=QString::number(context.line);
+ }
+ if (context.function && !QString(context.function).isEmpty()) {
+ report+=+" function ";
+ report+=QString(context.function);
+ }
+ const char*const local=report.toLocal8Bit().constData();
+ switch (type) {
+ case QtDebugMsg:
+ __android_log_write(ANDROID_LOG_DEBUG,applicationName,local);
+ break;
+ case QtInfoMsg:
+ __android_log_write(ANDROID_LOG_INFO,applicationName,local);
+ break;
+ case QtWarningMsg:
+ __android_log_write(ANDROID_LOG_WARN,applicationName,local);
+ break;
+ case QtCriticalMsg:
+ __android_log_write(ANDROID_LOG_ERROR,applicationName,local);
+ break;
+ case QtFatalMsg:
+ default:
+ __android_log_write(ANDROID_LOG_FATAL,applicationName,local);
+ abort();
+ }
+}
+#endif
diff --git a/android/sound.cpp b/android/sound.cpp
index 0b2ae651..ae28508a 100644
--- a/android/sound.cpp
+++ b/android/sound.cpp
@@ -2,7 +2,7 @@
* Copyright (c) 2004-2020
*
* Author(s):
- * Volker Fischer
+ * Simon Tomlinson
*
******************************************************************************
*
@@ -23,256 +23,157 @@
\******************************************************************************/
#include "sound.h"
-
+#include "androiddebug.cpp"
/* Implementation *************************************************************/
+
CSound::CSound ( void (*fpNewProcessCallback) ( CVector& psData, void* arg ),
void* arg,
const int iCtrlMIDIChannel,
const bool ,
const QString& ) :
CSoundBase ( "OpenSL", true, fpNewProcessCallback, arg, iCtrlMIDIChannel )
+
{
+ pSound = this;
+#ifdef ANDROIDDEBUG
+ qInstallMessageHandler(myMessageHandler);
+#endif
+}
+
+void CSound::setupCommonStreamParams(oboe::AudioStreamBuilder *builder)
+{
+ // We request EXCLUSIVE mode since this will give us the lowest possible
+ // latency. If EXCLUSIVE mode isn't available the builder will fall back to SHARED mode
+ builder->setCallback(this)
+ ->setFormat(oboe::AudioFormat::Float)
+ ->setSharingMode(oboe::SharingMode::Shared)
+ ->setChannelCount(oboe::ChannelCount::Mono)
+ // ->setSampleRate(48000)
+ // ->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)
+ ->setPerformanceMode(oboe::PerformanceMode::None);
+ return;
+}
+
+void CSound::openStreams()
+{
+ // Create callback
+ mCallback = this;
+
+ //Setup output stream
+ oboe::AudioStreamBuilder inBuilder, outBuilder;
+ outBuilder.setDirection(oboe::Direction::Output);
+ setupCommonStreamParams(&outBuilder);
+ oboe::Result result = outBuilder.openManagedStream(mPlayStream);
+ if (result != oboe::Result::OK) {
+ return;
+ }
+ mPlayStream->setBufferSizeInFrames(pSound->iOpenSLBufferSizeStereo);
+
+ warnIfNotLowLatency(mPlayStream, "PlayStream");
+ printStreamDetails(mPlayStream);
+
+ //Setup input stream
+ inBuilder.setDirection(oboe::Direction::Input);
+ setupCommonStreamParams(&inBuilder);
+ result = inBuilder.openManagedStream(mRecordingStream);
+ if (result != oboe::Result::OK) {
+ closeStream(mPlayStream);
+ return;
+ }
+ mRecordingStream->setBufferSizeInFrames(pSound->iOpenSLBufferSizeStereo);
+
+ warnIfNotLowLatency(mRecordingStream, "RecordStream");
+ printStreamDetails(mRecordingStream);
+}
+
+void CSound::printStreamDetails(oboe::ManagedStream &stream)
+{
+
+ QString sDirection = (stream->getDirection()==oboe::Direction::Input?"Input":"Output");
+ QString sFramesPerBurst = QString::number(stream->getFramesPerBurst());
+ QString sBufferSizeInFrames = QString::number(stream->getBufferSizeInFrames());
+ QString sBytesPerFrame = QString::number(stream->getBytesPerFrame());
+ QString sBytesPerSample = QString::number(stream->getBytesPerSample());
+ QString sBufferCapacityInFrames = QString::number(stream->getBufferCapacityInFrames());
+ QString sPerformanceMode = (stream->getPerformanceMode()==oboe::PerformanceMode::LowLatency?"LowLatency":"NotLowLatency");
+ QString sSharingMode = (stream->getSharingMode() == oboe::SharingMode::Exclusive?"Exclusive":"Shared");
+ QString sDeviceID = QString::number(stream->getDeviceId());
+ QString sSampleRate = QString::number(stream->getSampleRate());
+ QString sAudioFormat = (stream->getFormat()==oboe::AudioFormat::I16?"I16":"Float");
+
+ QString sFramesPerCallback = QString::number(stream->getFramesPerCallback());
+ //QString sSampleRateConversionQuality = (stream.getSampleRateConversionQuality()==oboe::SampleRateConversionQuality::
+
+ qInfo() << "Stream details: [sDirection: " << sDirection <<
+ ", FramesPerBurst: " << sFramesPerBurst <<
+ ", BufferSizeInFrames: " << sBufferSizeInFrames <<
+ ", BytesPerFrame: " << sBytesPerFrame <<
+ ", BytesPerSample: " << sBytesPerSample <<
+ ", BufferCapacityInFrames: " << sBufferCapacityInFrames <<
+ ", PerformanceMode: " << sPerformanceMode <<
+ ", SharingMode: " << sSharingMode <<
+ ", DeviceID: " << sDeviceID <<
+ ", SampleRate: " << sSampleRate <<
+ ", AudioFormat: " << sAudioFormat <<
+ ", FramesPerCallback: " << sFramesPerCallback << "]";
}
-void CSound::InitializeOpenSL()
-{
- // set up stream formats for input and output
- SLDataFormat_PCM inStreamFormat;
- inStreamFormat.formatType = SL_DATAFORMAT_PCM;
- inStreamFormat.numChannels = 1;
- inStreamFormat.samplesPerSec = SL_SAMPLINGRATE_16;
- inStreamFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
- inStreamFormat.containerSize = 16;
- inStreamFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
- inStreamFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
-
- SLDataFormat_PCM outStreamFormat;
- outStreamFormat.formatType = SL_DATAFORMAT_PCM;
- outStreamFormat.numChannels = 2;
- outStreamFormat.samplesPerSec = SYSTEM_SAMPLE_RATE_HZ * 1000; // unit is mHz
- outStreamFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
- outStreamFormat.containerSize = 16;
- outStreamFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
- outStreamFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
-
- // create the OpenSL root engine object
- slCreateEngine ( &engineObject,
- 0,
- nullptr,
- 0,
- nullptr,
- nullptr );
-
- // realize the engine
- (*engineObject)->Realize ( engineObject,
- SL_BOOLEAN_FALSE );
-
- // get the engine interface (required to create other objects)
- (*engineObject)->GetInterface ( engineObject,
- SL_IID_ENGINE,
- &engine );
-
- // create the main output mix
- (*engine)->CreateOutputMix ( engine,
- &outputMixObject,
- 0,
- nullptr,
- nullptr );
-
- // realize the output mix
- (*outputMixObject)->Realize ( outputMixObject,
- SL_BOOLEAN_FALSE );
-
- // configure the audio (data) source for input
- SLDataLocator_IODevice micLocator;
- micLocator.locatorType = SL_DATALOCATOR_IODEVICE;
- micLocator.deviceType = SL_IODEVICE_AUDIOINPUT;
- micLocator.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
- micLocator.device = nullptr;
-
- SLDataSource inDataSource;
- inDataSource.pLocator = &micLocator;
- inDataSource.pFormat = nullptr;
-
- // configure the input buffer queue
- SLDataLocator_AndroidSimpleBufferQueue inBufferQueue;
- inBufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- inBufferQueue.numBuffers = 2; // max number of buffers in queue
-
- // configure the audio (data) sink for input
- SLDataSink inDataSink;
- inDataSink.pLocator = &inBufferQueue;
- inDataSink.pFormat = &inStreamFormat;
-
- // create the audio recorder
- const SLInterfaceID recorderIds[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
- const SLboolean recorderReq[] = { SL_BOOLEAN_TRUE };
-
- (*engine)->CreateAudioRecorder ( engine,
- &recorderObject,
- &inDataSource,
- &inDataSink,
- 1,
- recorderIds,
- recorderReq );
-
- // realize the audio recorder
- (*recorderObject)->Realize ( recorderObject,
- SL_BOOLEAN_FALSE );
-
- // get the audio recorder interface
- (*recorderObject)->GetInterface ( recorderObject,
- SL_IID_RECORD,
- &recorder );
-
- // get the audio recorder simple buffer queue interface
- (*recorderObject)->GetInterface ( recorderObject,
- SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &recorderSimpleBufQueue );
-
- // register the audio input callback
- (*recorderSimpleBufQueue)->RegisterCallback ( recorderSimpleBufQueue,
- processInput,
- this );
-
- // configure the output buffer queue
- SLDataLocator_AndroidSimpleBufferQueue outBufferQueue;
- outBufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- outBufferQueue.numBuffers = 2; // max number of buffers in queue
-
- // configure the audio (data) source for output
- SLDataSource outDataSource;
- outDataSource.pLocator = &outBufferQueue;
- outDataSource.pFormat = &outStreamFormat;
-
- // configure the output mix
- SLDataLocator_OutputMix outputMix;
- outputMix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
- outputMix.outputMix = outputMixObject;
-
- // configure the audio (data) sink for output
- SLDataSink outDataSink;
- outDataSink.pLocator = &outputMix;
- outDataSink.pFormat = nullptr;
-
- // create the audio player
- const SLInterfaceID playerIds[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
- const SLboolean playerReq[] = { SL_BOOLEAN_TRUE };
-
- (*engine)->CreateAudioPlayer ( engine,
- &playerObject,
- &outDataSource,
- &outDataSink,
- 1,
- playerIds,
- playerReq );
-
- // realize the audio player
- (*playerObject)->Realize ( playerObject,
- SL_BOOLEAN_FALSE );
-
- // get the audio player interface
- (*playerObject)->GetInterface ( playerObject,
- SL_IID_PLAY,
- &player );
-
- // get the audio player simple buffer queue interface
- (*playerObject)->GetInterface ( playerObject,
- SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &playerSimpleBufQueue );
-
- // register the audio output callback
- (*playerSimpleBufQueue)->RegisterCallback ( playerSimpleBufQueue,
- processOutput,
- this );
+void CSound::warnIfNotLowLatency(oboe::ManagedStream &stream, QString streamName) {
+ if (stream->getPerformanceMode() != oboe::PerformanceMode::LowLatency) {
+ QString latencyMode = (stream->getPerformanceMode()==oboe::PerformanceMode::None ? "None" : "Power Saving");
+ // throw CGenErr ( tr ( "Stream is NOT low latency."
+ // "Check your requested format, sample rate and channel count." ) );
+ }
}
-void CSound::CloseOpenSL()
+void CSound::closeStream(oboe::ManagedStream &stream)
+{
+ if (stream) {
+ oboe::Result requestStopRes = stream->requestStop();
+ oboe::Result result = stream->close();
+ if (result != oboe::Result::OK) {
+ throw CGenErr ( tr ( "Error closing stream: $s",
+ oboe::convertToText(result) ) );
+ }
+ stream.reset();
+ }
+}
+
+void CSound::closeStreams()
{
// clean up
- (*recorderObject)->Destroy ( recorderObject );
- (*playerObject)->Destroy ( playerObject );
- (*outputMixObject)->Destroy ( outputMixObject );
- (*engineObject)->Destroy ( engineObject );
+ closeStream(mRecordingStream);
+ closeStream(mPlayStream);
}
void CSound::Start()
{
- InitializeOpenSL();
-
-// TEST We have to supply the interface with initial buffers, otherwise
-// the rendering will not start.
-// Note that the number of buffers enqueued here must match the maximum
-// numbers of buffers configured in the constructor of this class.
-vecsTmpAudioSndCrdStereo.Reset ( 0 );
-
- // enqueue initial buffers for record
- (*recorderSimpleBufQueue)->Enqueue ( recorderSimpleBufQueue,
- &vecsTmpAudioSndCrdStereo[0],
- iOpenSLBufferSizeStereo * 2 /* 2 bytes */ );
-
- (*recorderSimpleBufQueue)->Enqueue ( recorderSimpleBufQueue,
- &vecsTmpAudioSndCrdStereo[0],
- iOpenSLBufferSizeStereo * 2 /* 2 bytes */ );
-
- // enqueue initial buffers for playback
- (*playerSimpleBufQueue)->Enqueue ( playerSimpleBufQueue,
- &vecsTmpAudioSndCrdStereo[0],
- iOpenSLBufferSizeStereo * 2 /* 2 bytes */ );
-
- (*playerSimpleBufQueue)->Enqueue ( playerSimpleBufQueue,
- &vecsTmpAudioSndCrdStereo[0],
- iOpenSLBufferSizeStereo * 2 /* 2 bytes */ );
-
- // start the rendering
- (*recorder)->SetRecordState ( recorder, SL_RECORDSTATE_RECORDING );
- (*player)->SetPlayState ( player, SL_PLAYSTATE_PLAYING );
+ openStreams();
// call base class
CSoundBase::Start();
+
+ // finally start the streams so the callback begins, start with inputstream first.
+ mRecordingStream->requestStart();
+ mPlayStream->requestStart();
+
}
void CSound::Stop()
{
- // stop the audio stream
- (*recorder)->SetRecordState ( recorder, SL_RECORDSTATE_STOPPED );
- (*player)->SetPlayState ( player, SL_PLAYSTATE_STOPPED );
-
- // clear the buffers
- (*recorderSimpleBufQueue)->Clear ( recorderSimpleBufQueue );
- (*playerSimpleBufQueue)->Clear ( playerSimpleBufQueue );
+ closeStreams();
// call base class
CSoundBase::Stop();
-
- CloseOpenSL();
}
int CSound::Init ( const int iNewPrefMonoBufferSize )
{
-
-
-// TODO make use of the following:
-// String sampleRate = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
-// String framesPerBuffer = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
-/*
-// get the Audio IO DEVICE CAPABILITIES interface
-SLAudioIODeviceCapabilitiesItf audioCapabilities;
-
-(*engineObject)->GetInterface ( engineObject,
- SL_IID_AUDIOIODEVICECAPABILITIES,
- &audioCapabilities );
-
-(*audioCapabilities)->QueryAudioInputCapabilities ( audioCapabilities,
- inputDeviceIDs[i],
- &audioInputDescriptor );
-*/
-
-
// store buffer size
- iOpenSLBufferSizeMono = iNewPrefMonoBufferSize;
+ iOpenSLBufferSizeMono = 512 ;
+ //iNewPrefMonoBufferSize;
// init base class
CSoundBase::Init ( iOpenSLBufferSizeMono );
@@ -283,7 +184,6 @@ SLAudioIODeviceCapabilitiesItf audioCapabilities;
// create memory for intermediate audio buffer
vecsTmpAudioSndCrdStereo.Init ( iOpenSLBufferSizeStereo );
-
// TEST
#if ( SYSTEM_SAMPLE_RATE_HZ != 48000 )
# error "Only a system sample rate of 48 kHz is supported by this module"
@@ -296,57 +196,105 @@ SLAudioIODeviceCapabilitiesItf audioCapabilities;
iModifiedInBufSize = iOpenSLBufferSizeMono / 3;
vecsTmpAudioInSndCrd.Init ( iModifiedInBufSize );
-
return iOpenSLBufferSizeMono;
}
-void CSound::processInput ( SLAndroidSimpleBufferQueueItf bufferQueue,
- void* instance )
+// This is the main callback method for when an audio stream is ready to publish data to an output stream
+// or has received data on an input stream. As per manual much be very careful not to do anything in this back that
+// can cause delays such as sleeping, file processing, allocate memory, etc
+oboe::DataCallbackResult CSound::onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames)
{
- CSound* pSound = static_cast ( instance );
+ // only process if we are running
+ if ( ! pSound->bRun )
+ {
+ return oboe::DataCallbackResult::Continue;
+ }
- // only process if we are running
- if ( !pSound->bRun )
+ // Need to modify the size of the buffer based on the numFrames requested in this callback.
+ // Buffer size can change regularly by android devices
+ int& iBufferSizeMono = pSound->iOpenSLBufferSizeMono;
+
+ // perform the processing for input and output
+// QMutexLocker locker ( &pSound->Mutex );
+ // locker.mutex();
+
+ //This can be called from both input and output at different times
+ if (oboeStream == pSound->mPlayStream.get() && audioData)
{
- return;
+ float *floatData = static_cast(audioData);
+
+ // Zero out the incoming container array
+ memset(audioData, 0, sizeof(float) * numFrames * oboeStream->getChannelCount());
+
+ // Only copy data if we have data to copy, otherwise fill with silence
+ if (!pSound->vecsTmpAudioSndCrdStereo.empty())
+ {
+ for (int frmNum = 0; frmNum < numFrames; ++frmNum)
+ {
+ for (int channelNum = 0; channelNum < oboeStream->getChannelCount(); channelNum++)
+ {
+ // copy sample received from server into output buffer
+
+
+ // convert to 32 bit
+ const int32_t iCurSam = static_cast (
+ pSound->vecsTmpAudioSndCrdStereo [frmNum * oboeStream->getChannelCount() + channelNum] );
+ floatData[frmNum * oboeStream->getChannelCount() + channelNum] = (float) iCurSam/ _MAXSHORT;
+ }
+ }
+ }
+ else
+ {
+ // prime output stream buffer with silence
+ memset(static_cast(audioData) + numFrames * oboeStream->getChannelCount(), 0,
+ (numFrames) * oboeStream->getBytesPerFrame());
+ }
}
-
- QMutexLocker locker ( &pSound->Mutex );
-
- // enqueue the buffer for record
- (*bufferQueue)->Enqueue ( bufferQueue,
- &pSound->vecsTmpAudioInSndCrd[0],
- pSound->iModifiedInBufSize * 2 /* 2 bytes */ );
-
-// upsampling (without filtering) and channel management
-pSound->vecsTmpAudioSndCrdStereo.Reset ( 0 );
-for ( int i = 0; i < pSound->iModifiedInBufSize; i++ )
-{
- pSound->vecsTmpAudioSndCrdStereo[6 * i] =
- pSound->vecsTmpAudioSndCrdStereo[6 * i + 1] =
- pSound->vecsTmpAudioInSndCrd[i];
-}
-
-}
-
-void CSound::processOutput ( SLAndroidSimpleBufferQueueItf bufferQueue,
- void* instance )
-{
- CSound* pSound = static_cast ( instance );
-
- // only process if we are running
- if ( !pSound->bRun )
+ else if (oboeStream == pSound->mRecordingStream.get() && audioData)
{
- return;
+ // First things first, we need to discard the input queue a little for 500ms or so
+ if (pSound->mCountCallbacksToDrain > 0)
+ {
+ // discard the input buffer
+ int32_t numBytes = numFrames * oboeStream->getBytesPerFrame();
+ memset(audioData, 0 /* value */, numBytes);
+ pSound->mCountCallbacksToDrain--;
+ }
+
+ // We're good to start recording now
+ // Take the data from the recording device ouput buffer and move
+ // it to the vector ready to send up to the server
+
+ float *floatData = static_cast(audioData);
+
+ // Copy recording data to internal vector
+ for (int frmNum = 0; frmNum < numFrames; ++frmNum)
+ {
+ for (int channelNum = 0; channelNum < oboeStream->getChannelCount(); channelNum++)
+ {
+ pSound->vecsTmpAudioSndCrdStereo [frmNum * oboeStream->getChannelCount() + channelNum] =
+ (short) floatData[frmNum * oboeStream->getChannelCount() + channelNum] * _MAXSHORT;
+ }
+ }
+
+ // Tell parent class that we've put some data ready to send to the server
+ pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo );
}
-
- QMutexLocker locker ( &pSound->Mutex );
-
- // call processing callback function
- pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo );
-
- // enqueue the buffer for playback
- (*bufferQueue)->Enqueue ( bufferQueue,
- &pSound->vecsTmpAudioSndCrdStereo[0],
- pSound->iOpenSLBufferSizeStereo * 2 /* 2 bytes */ );
+ // locker.unlock();
+ return oboe::DataCallbackResult::Continue;
}
+
+//TODO better handling of stream closing errors
+void CSound::onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result result)
+{
+ qDebug() << "CSound::onErrorAfterClose";
+}
+
+//TODO better handling of stream closing errors
+void CSound::onErrorBeforeClose(oboe::AudioStream *oboeStream, oboe::Result result)
+{
+ qDebug() << "CSound::onErrorBeforeClose";
+}
+
+
+
diff --git a/android/sound.h b/android/sound.h
index 6ab4c34b..535694b7 100644
--- a/android/sound.h
+++ b/android/sound.h
@@ -2,7 +2,7 @@
* Copyright (c) 2004-2020
*
* Author(s):
- * Volker Fischer
+ * Simon Tomlinson
*
******************************************************************************
*
@@ -24,15 +24,18 @@
#pragma once
-#include
-#include
+/* Deprecated, moving to OBOE
+ * #include
+ * #include */
+#include
#include
#include "soundbase.h"
#include "global.h"
-
+#include
+#include
/* Classes ********************************************************************/
-class CSound : public CSoundBase
+class CSound : public CSoundBase, public oboe::AudioStreamCallback//, public IRenderableAudio, public IRestartable
{
public:
CSound ( void (*fpNewProcessCallback) ( CVector& psData, void* arg ),
@@ -46,10 +49,30 @@ public:
virtual void Start();
virtual void Stop();
+ // Call backs for Oboe
+ virtual oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames);
+ virtual void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result result);
+ virtual void onErrorBeforeClose(oboe::AudioStream *oboeStream, oboe::Result result);
+
// these variables should be protected but cannot since we want
// to access them from the callback function
CVector vecsTmpAudioSndCrdStereo;
+ static void android_message_handler(QtMsgType type,
+ const QMessageLogContext &context,
+ const QString &message)
+ {
+ android_LogPriority priority = ANDROID_LOG_DEBUG;
+ switch (type) {
+ case QtDebugMsg: priority = ANDROID_LOG_DEBUG; break;
+ case QtWarningMsg: priority = ANDROID_LOG_WARN; break;
+ case QtCriticalMsg: priority = ANDROID_LOG_ERROR; break;
+ case QtFatalMsg: priority = ANDROID_LOG_FATAL; break;
+ };
+
+ __android_log_print(priority, "Qt", "%s", qPrintable(message));
+ };
+
// TEST
CVector vecsTmpAudioInSndCrd;
int iModifiedInBufSize;
@@ -57,27 +80,25 @@ int iModifiedInBufSize;
int iOpenSLBufferSizeMono;
int iOpenSLBufferSizeStereo;
-protected:
+private:
+ void setupCommonStreamParams(oboe::AudioStreamBuilder *builder);
+ void printStreamDetails(oboe::ManagedStream &stream);
+ void openStreams();
+ void closeStreams();
+ void warnIfNotLowLatency(oboe::ManagedStream &stream, QString streamName);
+ void closeStream(oboe::ManagedStream &stream);
- void InitializeOpenSL();
- void CloseOpenSL();
+ oboe::ManagedStream mRecordingStream;
+ oboe::ManagedStream mPlayStream;
+ AudioStreamCallback *mCallback;
- // callbacks
- static void processInput ( SLAndroidSimpleBufferQueueItf bufferQueue,
- void* instance );
+ // used to reach a state where the input buffer is
+ // empty and the garbage in the first 500ms or so is discarded
+ static constexpr int32_t kNumCallbacksToDrain = 10;
+ int32_t mCountCallbacksToDrain = kNumCallbacksToDrain;
- static void processOutput ( SLAndroidSimpleBufferQueueItf bufferQueue,
- void* instance );
-
- SLObjectItf engineObject;
- SLEngineItf engine;
- SLObjectItf recorderObject;
- SLRecordItf recorder;
- SLAndroidSimpleBufferQueueItf recorderSimpleBufQueue;
- SLObjectItf outputMixObject;
- SLObjectItf playerObject;
- SLPlayItf player;
- SLAndroidSimpleBufferQueueItf playerSimpleBufQueue;
+ // Used to reference this instance of class from within the static callback
+ CSound *pSound;
QMutex Mutex;
diff --git a/libs/oboe b/libs/oboe
new file mode 160000
index 00000000..55d878a4
--- /dev/null
+++ b/libs/oboe
@@ -0,0 +1 @@
+Subproject commit 55d878a4e85e1994f2b5883366079b991500a25f
diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp
index eefc122a..ab178cd4 100755
--- a/src/clientdlg.cpp
+++ b/src/clientdlg.cpp
@@ -117,7 +117,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
// reverberation level
QString strAudReverb = "" + tr ( "Reverberation Level" ) + ": " +
tr ( "A reverberation effect can be applied to one local mono audio channel or to both "
- "channels in stereo mode. The mone channel selection and the "
+ "channels in stereo mode. The mono channel selection and the "
"reverberation level can be modified. If, e.g., "
"the microphone signal is fed into the right audio channel of the "
"sound card and a reverberation effect shall be applied, set the "
diff --git a/src/global.h b/src/global.h
index 24195fa9..de7a0783 100755
--- a/src/global.h
+++ b/src/global.h
@@ -258,6 +258,8 @@ typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
+#elif defined ( ANDROID )
+// don't redfine types for android as these ones below don't work
#else
typedef long long int64_t;
typedef int int32_t;
diff --git a/src/main.cpp b/src/main.cpp
index 6def9cb6..fa615518 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -33,12 +33,16 @@
#include "settings.h"
#include "testbench.h"
#include "util.h"
+#ifdef ANDROID
+# include
+#endif
// Implementation **************************************************************
int main ( int argc, char** argv )
{
+
QTextStream& tsConsole = *( ( new ConsoleWriterFactory() )->get() );
QString strArgument;
double rDbleArgument;
@@ -60,6 +64,7 @@ int main ( int argc, char** argv )
bool bCentServPingServerInList = false;
bool bNoAutoJackConnect = false;
bool bUseTranslation = true;
+ bool bCustomPortNumberGiven = false;
int iNumServerChannels = DEFAULT_USED_NUM_CHANNELS;
int iMaxDaysHistory = DEFAULT_DAYS_HISTORY;
int iCtrlMIDIChannel = INVALID_MIDI_CH;
@@ -77,13 +82,6 @@ int main ( int argc, char** argv )
QString strWelcomeMessage = "";
QString strClientName = APP_NAME;
- // adjust default port number for client: use different default port than the server since
- // if the client is started before the server, the server would get a socket bind error
- if ( bIsClient )
- {
- iPortNumber += 10; // increment by 10
- }
-
// QT docu: argv()[0] is the program name, argv()[1] is the first
// argument and argv()[argc()-1] is the last argument.
// Start with first argument, therefore "i = 1"
@@ -312,7 +310,8 @@ int main ( int argc, char** argv )
65535,
rDbleArgument ) )
{
- iPortNumber = static_cast ( rDbleArgument );
+ iPortNumber = static_cast ( rDbleArgument );
+ bCustomPortNumberGiven = true;
tsConsole << "- selected port number: " << iPortNumber << endl;
continue;
}
@@ -507,17 +506,41 @@ int main ( int argc, char** argv )
strCentralServer = DEFAULT_SERVER_ADDRESS;
}
+ // adjust default port number for client: use different default port than the server since
+ // if the client is started before the server, the server would get a socket bind error
+ if ( bIsClient && !bCustomPortNumberGiven )
+ {
+ iPortNumber += 10; // increment by 10
+ }
- // Application/GUI setup ---------------------------------------------------
- // Application object
- if ( !bUseGUI && !strHistoryFileName.isEmpty() )
+ // display a warning if in server no GUI mode and a history file is requested
+ if ( !bIsClient && !bUseGUI && !strHistoryFileName.isEmpty() )
{
tsConsole << "Qt5 requires a windowing system to paint a JPEG image; image will use SVG" << endl;
}
+
+
+ // Application/GUI setup ---------------------------------------------------
+ // Application object
QCoreApplication* pApp = bUseGUI
? new QApplication ( argc, argv )
: new QCoreApplication ( argc, argv );
+#ifdef ANDROID
+ // special Android coded needed for record audio permission handling
+ auto result = QtAndroid::checkPermission ( QString ( "android.permission.RECORD_AUDIO" ) );
+
+ if ( result == QtAndroid::PermissionResult::Denied )
+ {
+ QtAndroid::PermissionResultMap resultHash = QtAndroid::requestPermissionsSync ( QStringList ( { "android.permission.RECORD_AUDIO" } ) );
+
+ if ( resultHash["android.permission.RECORD_AUDIO"] == QtAndroid::PermissionResult::Denied )
+ {
+ return 0;
+ }
+ }
+#endif
+
#ifdef _WIN32
// set application priority class -> high priority
SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
diff --git a/src/res/instruments/bongo.png b/src/res/instruments/bongo.png
new file mode 100644
index 00000000..3864cc70
Binary files /dev/null and b/src/res/instruments/bongo.png differ
diff --git a/src/res/instruments/bongo.svg b/src/res/instruments/bongo.svg
new file mode 100644
index 00000000..3a5f42fc
--- /dev/null
+++ b/src/res/instruments/bongo.svg
@@ -0,0 +1,142 @@
+
+
+
diff --git a/src/res/translation/translation_de_DE.qm b/src/res/translation/translation_de_DE.qm
index c4d9c9e2..296f9faf 100644
Binary files a/src/res/translation/translation_de_DE.qm and b/src/res/translation/translation_de_DE.qm differ
diff --git a/src/res/translation/translation_de_DE.ts b/src/res/translation/translation_de_DE.ts
index 43a40bb0..ed72c5c8 100644
--- a/src/res/translation/translation_de_DE.ts
+++ b/src/res/translation/translation_de_DE.ts
@@ -36,7 +36,7 @@
-
+ Qt plattformübergreifender Anwendungsrahmen
@@ -434,37 +434,37 @@
-
+ Lokaler Eingangsregler
-
+ Halleffekt Pegelregler
-
+ Auswahl linker Kanal für Halleffekt
-
+ Auswahl rechter Kanal für Halleffekt
-
+ Wenn diese LED rot leuchtet, dann wirst du keinen Spaß haben mit der
-
+ LED Stautuslampe für die Verzögerung
-
+ LED Statuslampe für den Netzwerkpuffer
@@ -531,82 +531,82 @@
-
+ Mit diesem Einstellregler kann der relative Pegel vom linken und rechten Eingangskanal verändert werden. Für ein Mono-Signal verhält sich der Regler wie ein Pan-Regler. Wenn, z.B., ein Mikrofon am rechten Kanal angeschlossen ist und das Instrument am linken Eingangskanal ist viel lauter als das Mikrofon, dann kann man den Lautstärkeunterschied mit diesem Regler kompensieren indem man den Regler in eine Richtung verschiebt, so dass über dem Regler
-
+ angezeigt wird, wobei
-
+ die aktuelle Dämpfung anzeigt.
-
+ Halleffektregler
-
-
+
+ Der Halleffekt kann auf einen selektierten Mono-Audiokanal oder auf beide Stereoaudiokanäle angewendet werden. Die Mono-Kanalselektion und die Hallstärke können eingestellt werden. Wenn z.B. ein Mikrofonsignal auf dem rechten Kanal anliegt und ein Halleffekt soll auf das Mikrofonsignal angewendet werden, dann muss die Hallkanalselektion auf rechts eingestellt werden und der Hallregler muss erhöht werden, bis die gewünschte Stärke des Halleffekts erreicht ist.
-
+ Die Berechnung des Halleffekts benötigt etwas Rechenleistung, so dass der Halleffekt nur bei schnellen Computern angewendet werden sollte. Wenn der Hallregler ganz nach unten gezogen ist, dann ist der Halleffekt ausgeschaltet und verbraucht keine Rechenleistung mehr.
-
+ Halleffekt Kanalselektion
-
+ Mit diesen Knöpfen kann ausgewählt werden, auf welches Eingangssignal der Halleffekt angewendet werden soll. Entweder der rechte oder linke Eingangskanal kann ausgewählt werden.
-
+ Status LED für die Verzögerung
-
+ Die Status-LED für die Verzögerung zeigt eine Bewertung der Gesamtverzögerung des Audiosignals. Wenn die LED grün leuchtet, dann ist die Verzögerung gering genug für das Jammen. Wenn die LED gelb anzeigt kann man noch spielen aber es wird schwieriger Lieder mit hohem Tempo zu spielen. Wenn die LED rot anzeigt, dann ist die Verzögerung zu hoch zum Jammen.
-
+ Status LED für den Netzwerkpuffer
-
+ Die Status-LED für den Netzwerkpuffer zeigt den aktuellen Status des Netzwerkstroms. Wenn die LED grün ist, dann gibt es keine Pufferprobleme. Wenn die LED rot anzeigt, dann ist der Netzwerkstrom kurz unterbrochen. Dies kann folgende Ursachen haben:
-
+ Der Netzwerkpuffer ist nicht groß genug eingestellt für die aktuellen Netzwerkbedingungen.
-
+ Der Soundkartenpuffer ist zu klein eingestellt.
-
+ Die Upload-Rate der Internetverbindung ist zu klein für den Netzwerkdatenstrom.
-
+ Die CPU des Computers ist voll ausgelastet.
@@ -674,7 +674,7 @@
-
+
@@ -702,377 +702,377 @@
- Netzwerkpuffergröße
+ Netzwerkpuffergröße
-
+ Der Netzwerkpuffer kompensiert die Netzwerk- und Soundkarten-Timing-Schwankungen. Die Größe des Netzwerkpuffers hat Auswirkungen auf die Qualität des Audiosignals (wie viele Aussetzer auftreten) und die Gesamtverzögerung (je länger der Puffer, desto größer ist die Verzögerung).
-
+ Die Netzwerkpuffergröße kann manuell verstellt werden, jeweils getrennt für die Applikation und den Server. Für den lokalen Netzwerkpuffer werden die Aussetzer durch die LED-Anzeige unter den Reglern angezeigt. Wenn die Lampe rot anzeigt, dann hat ein Pufferüberlauf oder ein Leerlauf des Puffers stattgefunden und der Audiodatenstrom wurde kurz unterbrochen.
-
+ Die Netzwerkpuffergröße ist deshalb ein Kompromiss zwischen Audioqualität und Gesamtverzögerung.
-
+ Die Netzwerkpuffergröße kann automatisch eingestellt werden. Wenn die Automatik aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des Servers getrennt basierend auf Messungen der Netzwerkschwankungen eingestellt. Wenn die Automatik aktiviert ist, dann sind die beiden Regler gesperrt für die manuelle Verstellung (sie können nicht mit der Maus verändert werden).
-
+ Wenn die Automatik zum Einstellen der Netzwerkpuffer aktiviert ist, dann werden die Netzwerkpuffer der Applikation und des entfernten Servers auf einen konservativen Wert eingestellt, um eine möglichst gute Audioqualität zu garantieren. Um die Gesamtverzögerung zu optimieren, bietet es sich an, die Automatik zu deaktivieren und die Netzwerkpuffer etwas kleiner einzustellen. Die Werte sollte man so weit reduzieren, bis die Audioqualität gerade noch der persönlichen Akkzeptanz entspricht. Die LED-Anzeige hilft dabei die Audioaussetzer verursacht durch den lokalen Netzwerkpuffer zu visualisieren (wenn die LED rot leuchtet).
-
+ Lokale Netzwerkpuffergröße Schieberegler
-
+ Server Netzwerkpuffergröße Schieberegler
-
+ Automatik für die Netzwerkpuffergröße aktivieren
-
+ Netzwerkpuffer Status LED
-
+ Soundkartengerät
-
+ Der ASIO-Treiber (Soundkarte) kann ausgewählt werden mit der
-
+ Software unter Windows. Unter MacOS und Linux kann man die Soundkarte nicht auswählen. Wenn der selektierte ASIO-Treiber nicht gültig ist, dann wird eine Fehlermeldung angezeigt und der vorherige gültige Treiber wird wieder ausgewählt.
-
+ Wenn der Treiber während eine aktiven Verbindung ausgewählt wird, dann wird die Verbindung gestoppt, der neue Treiber ausgewählt und anschließend wird die Verbindung automatisch wiederhergestellt.
-
+ Soundkarten Auswahlbox
-
+ Falls der ASIO4All-Treiber verwendet wird, kann es sein, dass dieser Treiber zusätzliche 10-30 ms Verzögerung hinzufügt. Aus diesem Grund sollte man bevorzugt einen nativen ASIO-Treiber der Soundkarte verwenden, der mit dem Produkt mitgeliefert wurde.
-
+ Falls der kx ASIO-Treiber verwendet wird, dann muss man darauf achten, dass die ASIO-Eingänge im kx DSP-Einstellungsfenster verbunden sind.
-
+ Soundkarten Kanalzuweisung
-
+ Falls die ausgewählte Soundkarte mehr als zwei Eingangs- oder Ausgangskanäle unterstützt, dann werden die Steuerelemente für die Kanalzuweisung angezeigt.
-
+ Für jeden
-
+ Eingangs-/Ausgangskanal (linker und rechter Kanal) kann ein beliebiger Soundkartenkanal zugewiesen werden.
-
+ Linker Eingang Kanalauswahlbox
-
+ Rechter Eingang Kanalauswahlbox
-
+ Linker Ausgang Kanalauswahlbox
-
+ Rechter Ausgang Kanalauswahlbox
- Aktiviere kleine Netzwerkpuffer
+ Aktiviere kleine Netzwerkpuffer
-
+ Falls aktiviert wird die Unterstützung für sehr kleine Netzwerk-Audiopakete aktiviert. Sehr kleine Netzwerkpakete werden nur dann verwendet, wenn der Soundkartenpuffer kleiner als
-
+ Samples ist. Je kleiner die Netzwerkpakete sind, desto kleiner ist auch die Audioverzögerung. Aber gleichzeitig wird dadurch die Netzwerklast erhöht und die Wahrscheinlichkeit für Audioaussetzer erhöht sich dadurch auch.
-
+ Aktiviere kleine Netzwerkpuffer Schalter
-
+ Soundkarten Puffergröße
-
+ Die Soundkartenpuffergröße ist eine fundamentale Einstellung der
-
+ Software. Diese Einstellung hat Einfluss auf viele andere Verbindungseigenschaften.
-
+ Drei Puffergrößen werden unterstützt
-
+ 64 Samples: Dies ist die bevorzugte Einstellung weil es die geringste Verzögerung hat. Diese Puffergröße funktioniert allerdings nicht mit allen Soundkarten.
-
+ 128 Samples: Diese Puffergröße sollte mit den meisten Soundkarten funktionieren.
-
+ 256 Samples: Diese Einstellung sollte nur dann verwendet werden, wenn man einen langsamen Computer oder eine langsame Internetverbindung hat.
-
+ Manche Soundkartentreiber unterstützen nicht das Verändern der Puffergröße innerhalb der
-
+ Software. In diesem Fall ist die Einstellungsmöglichkeit für die Puffergröße deaktiviert. Die Puffergröße muss man stattdessen direkt im Soundkartentreiber durchführen. Unter Windows kann man den ASIO-Einstellungen Knopf drücken um die Treibereinstellungen zu öffnen. Unter Linux benutzt man das Jack-Konfigurationsprogramm um die Puffergröße einzustellen.
-
+ Falls keiner der vorgegebenen Puffergrößen ausgeählt ist und alle Einstellungen deaktiviert sind, dann wird eine nicht unterstützte Puffergröße im Soundkartentreiber verwendet. Die
-
+ Software funktioniert trotzdem aber es könnte eine größere Verzögerung resultieren.
-
+ Die Puffergröße hat einen Einfluss auf den Verbindungsstatus, die aktuelle Upload-Rate und die Gesamtverzögerung. Je kleiner der Puffer, desto größer ist die Wahrscheinlichkeit für das Auftreten einer rot leuchtenden LED (was Audioaussetzer anzeigt), eine höheren Upload-Rate und eine niedrigere Gesamtverzögerung.
-
+ Die Puffergröße ist somit ein Kompromiss zwischen Audioqualität und Gesamtverzögerung.
-
+ Falls die Puffergröße nicht verstellt werden kann, dann hat der Soundkartentreiber die Einstellung gesperrt man kann es nicht innerhalb der
-
+ Software verändern. Unter Windows kann man den ASIO-Einstellungen Knopf drücken, um die Treibereinstellungen zu öffnen. Unter Linux kann man ein Jack-Konfigurationswerkzeug verwenden, um die Puffergröße zu verändern.
-
+ 128 Samples Einstellknopf
-
+ 256 Samples Einstellknopf
-
+ 512 Samples Einstellknopf
-
+ ASIO-Einstellungen Knopf
- Schicke Oberfläche
+ Schicke Oberfläche
-
+ Falls aktiviert wird eine schicke Oberfläche im Hauptfenster verwendet.
-
+ Schicke Oberfläche Schalter
- Zeige Kanalsignalpegel
+ Zeige Kanalsignalpegel
-
+ Falls aktiviert wird eine Signalpegelanzeige neben jedem Kanalfader angezeigt, welcher den Pegel vor dem Fader anzeigt.
-
+ Zeige Kanalpegel Schalter
- Audiokanäle
+ Audiokanäle
-
+ Hiermit kann man die Anzahl an Audiokanälen auswählen. Es gibt drei Modi. Die Mono- und Stereomodi verwenden jeweils einen oder zwei Kanäle. Im Mono-In/Stereo-Out Modus wird ein Monosignal zum Server geschickt aber es kommt ein Stereo-Signal zurück vom Server. Dies is nützlich für den Fall, dass man an die Soundkarte ein Instrument an den einen Eingangskanal und ein Mikrofon an den anderen Eingangskanal angeschlossen hat. In diesem Fall können die beiden Signale zusammen gemischt werden und an den Server geschickt werden aber man kann das Stereo-Signal von den anderen Musikern hören.
-
+ Wenn man den Stereo-Modus verwendet, dann ist die Übertragungsrate etwas höher. Man muss sicher stellen, dass die Internetverbindung die höhere Rate übertragen kann.
-
+ Wenn der Stereo-Modus ausgewählt wurde, dann verschwindet die Kanalselektion für den Halleffekt im Hauptfenster, da der Effekt auf beide Stereokanäle angewendet wird.
-
+ Audiokanal Auswahlbox
- Audioqualität
+ Audioqualität
-
+ Wählt die gewünschte Audioqualität aus. Es wird eine niedrige, mittlere und hohe Audioqualität angeboten. Je höher die Audioqualität, desto höher ist die Netzwerkübertragungsrate. Man muss sicherstellen, dass die Internetverbindung die höhere Rate übertragen kann.
-
+ Audioqualität Auswahlbox
- Pegel für neuen Teilnehmer
+ Pegel für neuen Teilnehmer
-
+ Der Pegel für neue Teilnehmer definiert die Fadereinstellung, wenn sich ein Teilnehmer neu mit dem Server verbindet. D.h. wenn ein neuer Fader erscheint, dann wird er auf den voreingestellten Pegel gesetzt. Eine Ausnahme bildet der Fall, dass der Teilnehmer vorher schon mal mit dem Server verbunden war und der Pegel gespeichert war.
-
+ Neuer Teilnehmer Pegel Einstellbox
-
+ Zentralserveradresse
-
+ Die Zentralserveradresse ist die IP-Adresse oder URL des Zentralservers, der die Serverlist organisiert und bereitstellt. Mit der Zentralserveradresse kann entweder die örtliche Region festgelegt werden (durch Auswahl des entsprechenden vorgegebenen Zentralservers) oder man gibt eine beliebige Adresse manuell ein.
-
+ Voreingestellter Zentralservertyp Auswahlbox
-
+ Zentralserveradresse Eingabefeld
-
+ Verbindungsstatus Parameter
-
+ Die Ping-Zeit ist die Zeit, die der Audiodatenstrom benötigt, um von der Applikation zum Server und zurück zu kommen. Diese Verzögerung wird vom Netzwerk hervorgerufen. Diese Verzögerung sollte so um die 20-30 ms sein. Falls die Verzögerung größer ist (z.B. 50-60 ms), der Abstand zum Server ist zu groß oder die Internetverbindung ist nicht ausreichend.
-
+ Die Gesamtverzögerung setzt sich zusammen aus der Ping-Zeit und die Verzögerung, die durch die Puffergrößen verursacht wird.
-
+ Die Upload-Rate hängt von der Soundkartenpuffergröße und die Audiokomprimierung ab. Man muss sicher stellen, dass die Upload-Rate immer kleiner ist als die Rate, die die Internetverbindung zur Verfügung stellt (man kann die Upload-Rate des Internetproviders z.B. mit speedtest.net überprüfen).
-
+ Wenn diese LED rot leuchtet, dann wirst du keinen Spaß haben mit der
- Software.
+ Software.
@@ -1087,7 +1087,7 @@
-
+ Mono-In/Stereo-Out
@@ -1148,17 +1148,17 @@
-
+ Das ausgewählte Audiogerät kann aus folgendem Grund nicht verwendet werden:
-
+ Der vorherige Treiber wird wieder ausgewählt.
-
+
@@ -1203,7 +1203,7 @@
- Aktiviere kleine Netzwerkpuffer
+ Aktiviere kleine Netzwerkpuffer
@@ -1294,7 +1294,7 @@
- Zentralserveradresse
+ Zentralserveradresse:
@@ -1306,7 +1306,7 @@
-
+ Wert
@@ -1324,82 +1324,82 @@
-
+ Severliste
-
+ Die Serverliste zeigt eine Liste von verfügbaren Server, die sich am Zentralserver registriert haben. Markiere einen Server von der Liste und drücke den Knopf Verbinden um eine Verbindung zu dem Server aufzubauen. Alternativ kann man auch den Server in der Liste direkt doppelklicken. Wenn ein Server belegt ist, dann wird eine Liste der verbundenen Musikern angezeigt. Server, die länger online sind (permanente Server) werden in Fettschrift dargestellt.
-
+ Es kann einen Moment dauern, bis die Serverliste vom Zentralserver empfangen wird. Falls keine gültige Zentralserveradresse in den Einstellungen angegeben ist, kann keine Liste angezeigt werden.
-
+ Serverliste Anzeige
-
+ Serveradresse
-
+ Die IP-Adresse oder URL des Servers, auf der die
-
+ Serversoftware läuft wird hier angegeben. Optional kann eine Portnummer angefügt werden. Diese wird hinter der IP-Adresse durch ein Doppelpunkt getrennt angegeben. Beispiel: example.org:
-
+ Eine Liste der letzten IP-Adressen oder URLs wird gespeichert und kann nachträglich wieder ausgewählt werden.
-
+ Serveradresse Eingabefeld
-
+ Enthält die aktuelle Server-IP-Adresse oder URL. Es speichert auch alte URLs in der Auswahlliste.
- Filter
+ Filter
-
+ Die Serverliste kann mit dem eingegebenen Text gefiltert werden, d.h. es werden nur Einträge angezeigt, die dem Filtertext entsprechen. Die Groß- und Kleinschreibung des Filtertexts wird dabei nicht beachtet.
-
+ Filtereingabefeld
- Zeige alle Teilnehmer
+ Zeige alle Teilnehmer
-
+ Ist diese Einstellung angehakt, dann werden alle Musiker auf allen Servern angezeigt. Wird der Haken entfernt, dann werden alle Listeneinträge eingeklappt und die verbundenen Musikernamen werden verborgen.
-
+ Zeige alle Teilnehmer Schalter
@@ -1504,7 +1504,7 @@
-
+ Durch das Verbinden mit diesem Server und das Akzeptieren des Lizenztextes willigst du folgenden Bedingungen ein:
@@ -1592,32 +1592,32 @@
-
+ -Server. Dieses Schild wird auch bei allen anderen Teilnehmern, die mit dem gleichen Server verbunden sind, angezeigt. Wenn der Name leer gelassen wurde, dann wird die IP-Adresse stattdessen angezeigt.
-
+ Alias oder Name Eingabefeld
-
+ Instrumentenbild Knopf
-
+ Landesflagge Knopf
-
+ Stadt Eingabefeld
-
+ Fähigkeit Auswahlbox
@@ -1670,7 +1670,7 @@
- Mittlere Spielstärke
+ Mittlere Spielstärke
@@ -1680,12 +1680,12 @@
-
+ Schreibe den Namen oder Alias hier rein so dass die anderen Musikern mit denen du spielst wissen wer du bist. Zusätzlich kannst du dein Instrument auswählen und eine Flagge des Landes auswählen in dem du dich befindest. Deine Stadt und deine Spielstärke des Instruments kannst du ebenso angeben.
-
+ Was man hier sieht wird auch am Fader im Mixer angezeigt, wenn du mit einem
@@ -1805,7 +1805,7 @@
-
+
@@ -1825,7 +1825,7 @@
-
+
@@ -1852,138 +1852,143 @@
Congas
+
+
+
+ Bongos
+ CServerDlg
-
+ Teilnehmerliste
-
+ Die Teilnehmerliste zeigt alle gerade mit dem Server verbunden Musiker an. Für jeden Teilnehmer werden zusätzliche Informationen wie die IP-Adresse und Namen angezeigt.
-
+ Teilnehmerliste
-
+ Starte minimiert beim Starten des Betriebssystems
-
+ Wenn diese Funktion angehakt ist, dann wird der
-
+ -Server automatisch mit dem Betriebssystemstart geladen und erscheint minimiert in der Systemleiste als Icon.
-
+ Zeige den Creative Commons Lizenzdialog
-
+ Falls aktiviert wird ein Create Commons BY-NC-SA 4.0 Lizenzdialog angezeigt, wenn ein neuer Teilnehmer versucht sich mit dem Server zu verbinden.
-
+ Veröffentliche meinen Server
-
+ Mit dieser Funktion wird der eigene Server in der Serverliste des Zentralservers registriert so dass alle anderen Applikationsnutzer den
-
+ -Server in der Liste sehen können und sich mit ihm verbinden können. Die Registrierung mit dem Zentralserver wird periodisch erneuert um sicherzugehen, dass alle registrierten Server auch wirklich erreichbar sind.
-
+ Registrierungsstatus
-
+ Wenn der eigene Server veröffentlicht wurde, dann zeigt der Registrierungsstatus and, ob die Registrierung erfolgreich war oder nicht.
-
+ Zentralserveradresse
-
+ Die Zentralserveradrees ist die IP-Adresse oder URL des Zentralservers bei dem man sich registrieren möchte. Mit dem Zentralservertyp legt man die Region fest, in der man sich befindet. Außerdem kann eine freie Adresse eingetragen werden.
-
+ Voreingestellter Zentralservertyp Auswahlbox
-
+ Zentralserveradresse Eingabefeld
- Servername
+ Servername
-
+ Der Servername identifiziert deinen Server in der Serverliste. Falls kein Name angegeben wurde, dann wird die IP-Adresse stattdessen angezeigt.
-
+ Servername Eingabefeld
-
+ Standort Stadt
-
+ Hier kann man die Stadt angeben, in der sich der Server befindet. Falls eine Stadt angegeben wurde, dann wird die in der Serverliste angezeigt.
-
+ Stadt in der sich der Server befindet Eingabefeld
-
+ Standort Land
-
+ Hier kann man das Land eingeben, in dem sich der Server befindet. Falls ein Land angegeben wurde, dann wird das in der Serverliste angezeigt.
-
+ Land in dem sich der Server befindet Auswahlbox
@@ -1994,14 +1999,14 @@
- Ausblenden vom
+ &Ausblenden vom
- -Server
+ -Server
@@ -2148,129 +2153,134 @@
-
+ Der Jack-Server läuft nicht. Diese Software benötigt aber einen Jack-Server um zu funktionieren. Normalerweise wird der Jack-Server automatisch gestartet. Es scheint so, als hätte dieser Automatismus nicht funktioniert. Versuche den Jack-Server manuell zu starten.
-
+ Die Jack-Server-Samplerate ist verschieden zu der benötigen. Die benötigte Samplerate ist:
-
+ Do kannst ein Werkzeug wie <i><a href=http://qjackctl.sourceforge.net>QJackCtl</a></li> verwenden um die Samplerate umzustellen.
-
+ Versichere dich, dass die Frames/Perioden auf einen niedrigen Wert wie z.B.
-
+ eingestellt ist um eine niedrige Verzögerung zu erreichen.
-
+ Die Jack-Portregistrierung ist fehlgeschlagen.
-
+ Der Jack-Client kann nicht aktiviert werden.
-
+ Der Jack-Server wurde gestoppt. Diese Software benötigt aber einen aktiven Jack-Server um zu funktionieren. Versuche die Software neu zu starten um das Problem zu lösen.
-
+ CoreAudio Eingang AudioHardwareGetProperty Aufruf schlug fehl. Es scheint als wäre keine Soundkarte im System vorhanden.
-
+ CoreAudio Ausgang AudioHardwareGetProperty Aufruf schlug fehl. Es scheint, dass keine Soundkarte ist im System verfügbar.
-
+ Die aktuelle Eingangssamplerate von %1 Hz wird nicht unterstützt. Bitte öffne die Audio-MIDI-Setup-Applikation in Applikationen->Werkzeuge und versuche die Samplerate auf %2 Hz einzustellen.
-
+ Die aktuelle Ausgangssamplerate von %1 Hz wird nicht unterstützt. Bitte öffne die Audio-MIDI-Setup-Applikation in Applikationen->Werkzeuge und versuche die Samplerate auf %2 Hz einzustellen.
-
+ Das Audioeingangsstromformat von diesem Audiogerät ist nicht kompatibel mit dieser Software.
-
+ Das Audioausgangsstromformat von diesem Audiogerät ist nicht kompatibel mit dieser Software.
-
+ Die Puffergrößen vom aktuellen Eingangs- und Ausgangsaudiogerät kann nicht auf einen gemeinsamen Wert eingestellt werden. Bitte wähle ein anderes Eingangs-/Ausgangsgerät aus der Geräteliste aus.
-
+ Der Audiotreiber konnte nicht initialisiert werden.
-
+ Das Audiogerät unterstützt nicht die benötigte Samplerate. Die benötigte Samplerate ist:
-
+ Das Audiogerät unterstützt nicht die benötigte Samplerate. Dieser Fehler kann auftreten, wenn ein Audiogerät wie das Roland UA-25EX verwendet wird, bei dem die Samplerate per Schalter am Gerät verstellt werden muss. Falls das der Fall sein sollte, dann stelle bitte den Schalter auf
-
+ Hz am Gerät und starte die
- Software.
+ Software neu.
-
+ Das Audiogerät unterstützt nicht die benötigte Anzahl an Kanälen. Die benötigte Anzahl an Kanälen für den Eingang und den Ausgang ist:
-
+ Das benötigte Audio Sampleformat ist nicht verfügbar.
-
+ Kein ASIO-Gerätetreiber wurde gefunden.
- Die
+ Die
-
+ Software benötigt aber ein ASIO Audiointerface um zu funktionieren. Dies ist keine Standard-Windowsschnittstelle und benötigt deshalb einen speziellen Treiber. Entweder die Soundkarte liefert einen nativen ASIO-Treiber mit (was empfohlen wird) oder man versucht es mit dem ASIO4All-Universaltreiber.
+
+
+
+
+ Fehler beim Schließen des Datenstroms: $s
@@ -2278,47 +2288,47 @@
-
+ Ungültige Geräteauswahl.
-
+ Die Audiotreibereigenschaften haben sich geändert. Die neuen Einstellungen sind nicht mehr kompatibel zu dieser Software. Das ausgewählte Audiogerät konnte nicht benutzt werden wegen folgendem Fehler:
-
+ Bitte starte die Software neu.
-
+
-
+ Kein benutzbares
-
+ Audiogerät (Treiber) konnte gefunden werden.
-
+ Im folgenden wird eine Liste aller gefundenen Audiogeräte mit entsprechender Fehlermeldung angezeigt:
-
+ Willst du die ASIO-Treibereinstellungen öffnen?
-
+ konnte nicht gestartet werden wegen Problemen mit dem Audiogerät.
diff --git a/src/res/translation/translation_es_ES.qm b/src/res/translation/translation_es_ES.qm
index 0605aee0..1b23987e 100644
Binary files a/src/res/translation/translation_es_ES.qm and b/src/res/translation/translation_es_ES.qm differ
diff --git a/src/res/translation/translation_es_ES.ts b/src/res/translation/translation_es_ES.ts
index 5651cdb5..db149121 100644
--- a/src/res/translation/translation_es_ES.ts
+++ b/src/res/translation/translation_es_ES.ts
@@ -554,7 +554,7 @@
-
+
Se puede aplicar un efecto de reverberación a un canal local de audio mono o a ambos canales en modo estéreo. Se puede modificar la selección de canales en modo mono y el nivel de reverberación. Por ej., si la señal del micrófono va por el canal derecho de la tarjeta de sonido y se desea aplicar reverberación, cambia el selector de canal a derecho y sube el fader hasta alcanzar el nivel de reverberación deseado.
@@ -1856,6 +1856,11 @@
Congas
+
+
+
+
+ CServerDlg
@@ -2276,6 +2281,11 @@
requiere la interfaz de audio de baja latencia ASIO para funcionar correctamente. No es una interfaz estándar de Windows y por tanto se requiere un driver de audio especial. Tu tarjeta de audio podría tener un driver ASIO nativo (lo recomendado) o quizá quieras probar un driver alternativo como ASIO4All.
+
+
+
+
+ CSoundBase
diff --git a/src/res/translation/translation_fr_FR.qm b/src/res/translation/translation_fr_FR.qm
index 8f6aee26..8d5adb43 100644
Binary files a/src/res/translation/translation_fr_FR.qm and b/src/res/translation/translation_fr_FR.qm differ
diff --git a/src/res/translation/translation_fr_FR.ts b/src/res/translation/translation_fr_FR.ts
index 5e3d648c..87a9eebb 100644
--- a/src/res/translation/translation_fr_FR.ts
+++ b/src/res/translation/translation_fr_FR.ts
@@ -15,22 +15,22 @@
-
+ permet aux musiciens de faire des bœufs en temps réel sur internet.
- serveur qui collecte les données audio de chaque
+ qui collecte les données audio de chaque client
-
+ Il existe un serveur
- client, mixe les données audio et renvoie le mixage à chaque client.
+ , mixe les données audio et renvoie le mixage à chaque client.
@@ -40,32 +40,32 @@
-
+ Cadriciel d'application multiplateforme Qt
-
+ Code de réverbération audio par Perry R. Cook et Gary P. Scavone
-
+ Certaines images sont issues de
-
+ Icônes de drapeaux de pays par Mark James
-
+ Pour plus de détails sur les contributions, consultez la
-
+ liste de contributeurs sur github
@@ -108,22 +108,22 @@
-
+ À &propos
-
+ Bib&liothèques
-
+ &Contributeurs
-
+ &Traduction
@@ -245,68 +245,68 @@
-
+ MUET
-
+ SOLO
-
+ Pseudo/nom
-
+ Instrument
- Localisation
+ Localisation
-
+ Niveau de compétence
-
+ Débutant
-
+ Intermédiaire
-
+ Expert
-
+ Profil de musicien
-
+ Muet
-
+ Solo
@@ -415,38 +415,38 @@
-
+ Bouton connecter/déconnecter
-
+ Appuyez sur ce bouton pour vous connecter à un serveur. Une boîte de dialogue vous permettant de sélectionner un serveur s'ouvrira. Si vous êtes connecté, l'appui sur ce bouton mettra fin à la session.
-
+ Bouton-bascule de connection/déconnexion
-
+ En cliquant sur ce bouton, la légende du bouton passe de Connecter à Déconnecter, c'est-à-dire qu'il met en œuvre une fonctionnalité de basculement pour connecter et déconnecter le logiciel
-
+ .
-
+ Chariot d'entrée audio locale
-
+ Chariot d'entrée audio locale (gauche/droite)
@@ -466,7 +466,7 @@
-
+ Si ce voyant devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser le logiciel
@@ -543,32 +543,32 @@
-
+ Avec le chariot audio, les niveaux relatifs des canaux audio locaux gauche et droit peuvent être modifiés. Pour un signal mono, il agit comme un panoramique entre les deux canaux. Si, par exemple, un microphone est connecté au canal d'entrée droit et qu'un instrument est connecté au canal d'entrée gauche qui est beaucoup plus fort que le microphone, déplacez le fader audio dans une direction où l'étiquette au-dessus du chariot indique
-
+ , où
-
+ est l'indicateur d'atténuation actuel.
-
+ Niveau de réverbération
-
-
+
+ Un effet de réverbération peut être appliqué à un canal audio mono local ou aux deux canaux en mode stéréo. La sélection du canal mono et le niveau de réverbération peuvent être modifiés. Si, par exemple, le signal du microphone est envoyé dans le canal audio droit de la carte son et qu'un effet de réverbération doit être appliqué, réglez le sélecteur de canal à droite et déplacez le curseur vers le haut jusqu'à ce que le niveau de réverbération souhaité soit atteint.
-
+ L'effet de réverbération nécessite un processeur important, de sorte qu'il ne doit être utilisé que sur des PC rapides. Si le chariot de niveau de réverbération est réglé au minimum (qui est le réglage par défaut), l'effet de réverbération est désactivé et n'entraîne aucune utilisation supplémentaire du processeur.
@@ -583,22 +583,22 @@
- LED d'état de délai
+ Voyant d'état de délai
- L'indicateur LED d'état de délai indique l'état actuel du délai audio. Si le voyant est vert, le délai est parfait pour une session de bœuf. Si le voyant est jaune, une session est toujours possible mais elle peut être plus difficile à jouer. Si le voyant est rouge, le délai est trop important pour un bœuf.
+ Le voyant d'état de délai indique l'état actuel du délai audio. Si le voyant est vert, le délai est parfait pour une session de bœuf. Si le voyant est jaune, une session est toujours possible mais elle peut être plus difficile à jouer. Si le voyant est rouge, le délai est trop important pour un bœuf.
- LED d'état de tampon
+ Voyant d'état de tampon
- L'indicateur LED d'état des tampons indique l'état actuel de l'audio/du streaming. Si le voyant est vert, il n'y a pas de dépassement de mémoire tampon ni de sous-dépassement et le flux audio n'est pas interrompu. Si le voyant est rouge, le flux audio est interrompu en raison de l'un des problèmes suivants :
+ Le voyant d'état des tampons indique l'état actuel de l'audio/du streaming. Si le voyant est vert, il n'y a pas de dépassement de mémoire tampon ni de sous-dépassement et le flux audio n'est pas interrompu. Si le voyant est rouge, le flux audio est interrompu en raison de l'un des problèmes suivants :
@@ -686,7 +686,7 @@
-
+ Pan
@@ -714,27 +714,27 @@
-
+ Taille du tampon de gigue
-
+ Le tampon de gigue compense les gigues de synchronisation du réseau et de l'interface audio. La taille de ce tampon de gigue a donc une influence sur la qualité du flux audio (combien de décrochages se produisent) et le délai global (plus le tampon est long, plus le délai est important).
-
+ La taille du tampon de gigue peut être choisie manuellement pour le client local et le serveur distant. Pour le tampon de gigue local, les désynchronisations dans le flux audio sont indiquées par le voyant situé en bas des chariots de taille du tampon de gigue. Si le voyant devient rouge, un dépassement de la taille de la mémoire tampon a eu lieu et le flux audio est interrompu.
-
+ Le réglage du tampon de gigue est donc un compromis entre la qualité audio et le délai global.
-
+ Un réglage automatique de la taille du tampon de gigue est disponible. Si la case Auto est activée, les tampons de gigue du client local et du serveur distant sont réglés automatiquement en fonction des mesures de la gigue de synchronisation du réseau et de la carte son. Si la case Auto est activée, les chariots de la taille du tampon de gigue sont désactivés (ils ne peuvent pas être déplacés avec la souris).
@@ -839,87 +839,87 @@
-
+ Activer les petits tampons de réseau
-
+ Si activée, la prise en charge des très petits paquets audio de réseau est activée. Les très petits paquets réseau ne sont réellement utilisés que si le délai de la mémoire tampon de la carte son est inférieur à
-
+ échantillons. Plus la mémoire tampon du réseau est petite, plus la latence audio est faible. Mais en même temps, la charge du réseau augmente et la probabilité de décrochage audio augmente également.
-
+ Cochez la case Activer les petits tampons de réseau
-
+ Délai de temporisation de l'interface audio
-
+ Le paramètre de délai de temporisation est un paramètre fondamental du logiciel
-
+ . Ce paramètre influence de nombreuses propriétés de connexion.
-
+ Trois tailles de tampon sont prises en charge
-
+ 64 échantillons : c'est le réglage préféré car il donne la latence la plus faible mais ne fonctionne pas avec toutes les interfaces audio.
-
+ 128 échantillons : ce réglage devrait fonctionner sur la plupart des interfaces audio disponibles.
-
+ 256 échantillons : ce paramètre ne doit être utilisé que si seul un ordinateur très lent ou une connexion internet lente est disponible.
-
+ Certains pilotes d'interface audio ne permettent pas de modifier le délai de la mémoire tampon à partir du logiciel
-
+ . Dans ce cas, le réglage du délai de mise en mémoire tampon est désactivé. Pour modifier le délai actuel de la mémoire tampon, ce paramètre doit être modifié dans le pilote de l'interface audio. Sous Windows, appuyez sur le bouton ASIO Setup pour ouvrir le panneau des paramètres du pilote. Sous Linux, utilisez l'outil de configuration Jack pour modifier la taille de la mémoire tampon.
-
+ Si aucune taille de tampon n'est sélectionnée et que tous les paramètres sont désactivés, une taille de tampon non prise en charge est utilisée par le pilote. Le logiciel
-
+ continuera toujours de fonctionner avec ce réglage, mais avec des performances limitées.
-
+ Le délai actuel de la mémoire tampon a une influence sur l'état de la connexion, le taux de téléchargement actuel et le délai global. Plus la taille de la mémoire tampon est faible, plus la probabilité d'un voyant rouge dans l'indicateur d'état (désynchronisations) est élevée, plus le taux de téléchargement est élevé et plus le délai global est faible.
-
+ Le réglage de la mémoire tampon est donc un compromis entre la qualité audio et le délai global.
@@ -954,52 +954,52 @@
-
+ Habillage fantaisie
-
+ Si activée, un habillage fantaisie sera appliqué à la fenêtre principale.
-
+ Cocher la case Habillage fantaisie
-
+ Afficher les niveaux des canaux
-
+ Si activée, chaque canal de client affichera une barre de niveau pré-fader.
-
+ Cocher la case Afficher les niveaux des canaux
-
+ Canaux audio
-
+ Sélectionnez le nombre de canaux audio à utiliser. Trois modes sont disponibles. Les modes mono et stéréo utilisent respectivement un et deux canaux audio. Dans le mode mono-in/stereo-out, le signal audio qui est envoyé au serveur est mono mais le signal de retour est stéréo. Ceci est utile dans le cas où l'interface audio place l'instrument sur un canal d'entrée et le microphone sur l'autre canal. Dans ce cas, les deux signaux d'entrée peuvent être mélangés dans un canal mono mais le mixage du serveur peut être entendu en stéréo.
-
+ L'activation du mode de streaming stéréo augmentera le débit de données du flux. Assurez-vous que le débit montant actuel ne dépasse pas la bande passante disponible de votre connexion internet.
-
+ Dans le cas du mode de streaming stéréo, aucune sélection de canal audio pour l'effet de réverbération ne sera disponible dans la fenêtre principale puisque l'effet est appliqué sur les deux canaux dans ce cas.
@@ -1009,12 +1009,12 @@
-
+ Qualité audio
-
+ Sélectionnez la qualité audio souhaitée. Une qualité audio faible, normale ou élevée peut être sélectionnée. Plus la qualité audio est élevée, plus le débit de données du flux audio est élevé. Assurez-vous que le débit montant actuel ne dépasse pas la bande passante disponible de votre connexion internet.
@@ -1024,12 +1024,12 @@
-
+ Niveau de nouveau client
-
+ Le paramètre de niveau de nouveau client définit le niveau de chariot d'un client nouvellement connecté en pourcentage. C'est-à-dire que si un nouveau client se connecte au serveur actuel, il aura le niveau de chariot initial spécifié si aucun autre niveau de chariot d'une connexion précédente de ce client n'était déjà stocké.
@@ -1039,12 +1039,12 @@
-
+ Adresse du serveur central
-
+ L'adresse du serveur central est l'adresse IP ou l'URL du serveur central sur lequel la liste des serveurs du dialogue de connexion est gérée. Avec le type d'adresse du serveur central, on peut soit sélectionner la région de localisation parmi les serveurs centraux par défaut, soit spécifier une adresse manuelle.
@@ -1059,32 +1059,32 @@
-
+ Paramètre de l'état de la connexion actuelle
-
+ Le temps de ping est le temps nécessaire pour que le flux audio voyage du client au serveur et vice-versa. Ce délai est introduit par le réseau. Ce délai doit être de 20 ou 30 ms. Si ce délai est supérieur (par exemple 50-60 ms), la distance qui vous sépare du serveur est trop importante ou votre connexion internet n'est pas suffisante.
-
+ Le délai global est calculé à partir du temps de ping actuel et du délai qui est introduit par les paramètres actuels de la mémoire tampon.
-
+ Le débit montant dépend de la taille actuelle du paquet audio et du réglage de la compression audio. Assurez-vous que le débit montant n'est pas supérieur au débit disponible (vérifiez les capacités montant de votre connexion internet en utilisant, par exemple, speedtest.net).
-
+ Si ce voyant devient rouge, vous n'aurez pas beaucoup de plaisir à utiliser le logiciel
-
+ .
@@ -1145,12 +1145,12 @@
-
+ Taille :
-
+ Délai de temporisation
@@ -1170,7 +1170,7 @@
-
+ Ok
@@ -1183,79 +1183,79 @@
-
+ Interface audio
-
+ Périphérique
-
+ Cartographie des canaux d'entrée
- G
+ G
- D
+ D
-
+ Cartographie des canaux de sortie
-
+ Activer les petits tampons de réseau
-
+ Délai de temporisation
-
+ (préféré)
-
+ (défaut)
-
+ (sûr)
-
+ Configuration du pilote
-
+ Tampon de gigue
-
+ Auto
-
+ Local
@@ -1271,64 +1271,64 @@
-
+ Divers
-
+ Canaux audio
-
+ Qualité audio
-
+ Niveau de nouveau client
-
+ %
-
+ Habillage fantaisie
-
+ Afficher les niveaux des canaux
-
+ Adresse du serveur central :
-
+ Débit du flux audio
-
+ val
- Temps de réponse
+ Temps de réponse
-
+ Délai global
@@ -1336,47 +1336,47 @@
-
+ Liste de serveurs
-
+ La liste de serveurs affiche une liste des serveurs disponibles qui sont enregistrés sur le serveur central. Sélectionnez un serveur dans la liste et appuyez sur le bouton de connexion pour vous connecter à ce serveur. Vous pouvez également double-cliquer sur un serveur de la liste pour vous y connecter. Si un serveur est occupé, une liste des musiciens connectés est disponible en développant l'élément de la liste. Les serveurs permanents sont indiqués en caractères gras.
-
+ Notez que ça peut prendre un certain temps pour récupérer la liste des serveurs depuis le serveur central. Si aucune adresse de serveur central valide n'est spécifiée dans les paramètres, aucune liste de serveurs ne sera disponible.
-
+ Vue de la liste de serveurs
-
+ Adresse du serveur
-
+ L'adresse IP ou l'URL du serveur qui exécute le logiciel serveur
-
+ doit être paramétré ici. Un numéro optionnel de port peut être ajouté après l'adresse IP ou l'URL en utilisant une virgule en tant que séparateur, par exemple, exemple.org :
-
+ Une liste des adresses IP ou URL de serveur les plus récentes est disponible pour la sélection.
-
+ Boîte d'édition de l'adresse du serveur
@@ -1386,7 +1386,7 @@
- Filtre
+ Filtre
@@ -1401,17 +1401,17 @@
- Afficher tous les musiciens
+ Afficher tous les musiciens
-
+ Si vous cochez cette case, les musiciens de tous les serveurs sont affichés. Si vous décochez la case, tous les éléments de la vue en liste sont regroupés.
-
+ Cochez la case Afficher tous les musiciens
@@ -1419,7 +1419,7 @@
-
+ Paramètres de connexion
@@ -1472,7 +1472,7 @@
-
+ &Aide
@@ -1614,80 +1614,80 @@
-
+ Bouton d'image d'instrument
-
+ Bouton de drapeau de pays
-
+ Boîte d'édition de la ville
-
+ Boîte combo de niveau de compétence
- Aucun
+ Aucune
-
+ Profil de musicien
-
+ Pseudo/nom
-
+ Instrument
-
+ Pays
-
+ Ville
-
+ Compétence
- &Fermer
+ &Fermer
-
+ Débutant
-
+ Intermédiaire
-
+ Expert
@@ -1702,167 +1702,172 @@
-
+ Batterie
-
+ Djembé
-
+ Guitare électrique
-
+ Guitare accoustique
-
+ Guitare basse
-
+ Clavier
-
+ Synthétiseur
-
+ Piano à queue
-
+ Accordéon
-
+ Voix
-
+ Microphone
-
+ Harmonica
-
+ Trompette
-
+ Trombone
-
+ Cor d'harmonie
-
+ Tuba
-
+ Saxophone
-
+ Clarinette
-
+ Flute
-
+ Violon
-
+ Violoncelle
-
+ Contrebasse
-
+ Enregistreur
-
+ Diffuseur
-
+ Auditeur
-
+ Guitare+voix
-
+ Clavier+voix
-
+ Bodhran
-
+ Basson
-
+ Hautbois
-
+ Harpe
-
+ Alto
-
+ Congas
+
+
+
+
+ Bongo
@@ -2107,7 +2112,7 @@
-
+ Taille du tampon de gigue
@@ -2132,7 +2137,7 @@
-
+ Adresse du serveur central :
@@ -2256,7 +2261,7 @@
-
+ .
@@ -2284,6 +2289,11 @@
+
+
+
+
+ CSoundBase
diff --git a/src/res/translation/translation_pt_PT.qm b/src/res/translation/translation_pt_PT.qm
index 8f7b9c79..b6fd9264 100644
Binary files a/src/res/translation/translation_pt_PT.qm and b/src/res/translation/translation_pt_PT.qm differ
diff --git a/src/res/translation/translation_pt_PT.ts b/src/res/translation/translation_pt_PT.ts
index 79e4ccf0..5df540ca 100644
--- a/src/res/translation/translation_pt_PT.ts
+++ b/src/res/translation/translation_pt_PT.ts
@@ -562,7 +562,7 @@
-
+
Um efeito de reverberação pode ser aplicado a um canal local de áudio mono ou a ambos os canais no modo estéreo. A seleção do canal mono e o nível de reverberação podem ser modificados. Se, por exemplo, o sinal do microfone for alimentado no canal de áudio direito da placa de som, e for aplicado um efeito de reverberação, ajuste o seletor de canal para a direita e mova o fader para cima até que o nível de reverberação desejado seja atingido.
@@ -1864,6 +1864,11 @@
+
+
+
+
+ CServerDlg
@@ -2284,6 +2289,11 @@
requer que a interface de áudio de baixa latência ASIO funcione corretamente. Esta não é uma interface de áudio padrão do Windows e, portanto, é necessário um driver de áudio especial. Ou a sua placa de som possui um driver ASIO nativo (recomendado), ou pode usar drivers alternativos, como o driver ASIO4All.
+
+
+
+
+ CSoundBase
diff --git a/src/resources.qrc b/src/resources.qrc
index 2c9c8476..51b5fe74 100755
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -67,6 +67,7 @@
res/instruments/harp.pngres/instruments/viola.pngres/instruments/congas.png
+ res/instruments/bongo.pngres/fronticon.png
diff --git a/src/util.cpp b/src/util.cpp
index 117a77a8..fff72c99 100755
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -999,6 +999,7 @@ CVector& CInstPictures::GetTable()
vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CMusProfDlg", "Harp" ), ":/png/instr/res/instruments/harp.png", IC_STRING_INSTRUMENT ) );
vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CMusProfDlg", "Viola" ), ":/png/instr/res/instruments/viola.png", IC_STRING_INSTRUMENT ) );
vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CMusProfDlg", "Congas" ), ":/png/instr/res/instruments/congas.png", IC_PERCUSSION_INSTRUMENT ) );
+ vecDataBase.Add ( CInstPictProps ( QCoreApplication::translate ( "CMusProfDlg", "Bongo" ), ":/png/instr/res/instruments/bongo.png", IC_PERCUSSION_INSTRUMENT ) );
// now the table is initialized
TableIsInitialized = true;