merge and clean

This commit is contained in:
Auzan Muhammad 2019-01-25 15:23:39 +07:00
commit f362194922
4 changed files with 61 additions and 61 deletions

View File

@ -42,7 +42,7 @@ set(MUMLIB_SRC
src/Audio.cpp src/Audio.cpp
) )
set(MUMLIB_LIBRARIES set(SPEEX_LIBRARIES
speex speex
speexdsp speexdsp
) )
@ -50,15 +50,15 @@ set(MUMLIB_LIBRARIES
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS Mumble.proto) PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS Mumble.proto)
add_library(mumlib SHARED ${MUMLIB_SRC} ${MUMLIB_PUBLIC_HEADERS} ${MUMLIB_PRIVATE_HEADERS} ${PROTO_SRCS} ${PROTO_HDRS}) add_library(mumlib SHARED ${MUMLIB_SRC} ${MUMLIB_PUBLIC_HEADERS} ${MUMLIB_PRIVATE_HEADERS} ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(mumlib ${MUMLIB_LIBRARIES}) target_link_libraries(mumlib
target_link_libraries(mumlib ${PROTOBUF_LIBRARIES}) ${SPEEX_LIBRARIES}
target_link_libraries(mumlib ${Boost_LIBRARIES}) ${PROTOBUF_LIBRARIES}
target_link_libraries(mumlib ${OPENSSL_LIBRARIES}) ${Boost_LIBRARIES}
target_link_libraries(mumlib ${LOG4CPP_LIBRARIES}) ${OPENSSL_LIBRARIES}
target_link_libraries(mumlib ${OPUS_LIBRARIES}) ${LOG4CPP_LIBRARIES}
${OPUS_LIBRARIES})
# add_executable(mumlib_example mumlib_example.cpp)
add_executable(mumlib_example mumlib_example.cpp) # target_link_libraries(mumlib_example mumlib)
target_link_libraries(mumlib_example mumlib)
install(TARGETS mumlib LIBRARY DESTINATION lib) install(TARGETS mumlib LIBRARY DESTINATION lib)

View File

@ -38,19 +38,19 @@ namespace mumlib {
void addFrameToBuffer(uint8_t *inputBuffer, int inputLength, int sequence); void addFrameToBuffer(uint8_t *inputBuffer, int inputLength, int sequence);
void fetchAudio(uint8_t *inputBuffer, int bufferOffset, int inputLength); // todo: mix audio
void mixAudio(uint8_t *dest, uint8_t *src, int bufferOffset, int inputLength);
void mixAudio(uint8_t *inputBuffer, uint8_t *outputBuffer, int bufferOffset, int inputLength);
void resizeBuffer(); void resizeBuffer();
std::pair<int, bool> decodeOpusPayload(int16_t *pcmBuffer,
int pcmBufferSize);
std::pair<int, bool> decodeOpusPayload(uint8_t *inputBuffer, std::pair<int, bool> decodeOpusPayload(uint8_t *inputBuffer,
int inputLength, int inputLength,
int16_t *pcmBuffer, int16_t *pcmBuffer,
int pcmBufferSize); int pcmBufferSize);
std::pair<int, bool> decodeOpusPayload(int16_t *pcmBuffer,
int pcmBufferSize);
int encodeAudioPacket( int encodeAudioPacket(
int target, int target,
@ -74,17 +74,15 @@ namespace mumlib {
OpusEncoder *opusEncoder; OpusEncoder *opusEncoder;
JitterBuffer *jbBuffer; JitterBuffer *jbBuffer;
mutex m_jitter_mutex;
int64_t outgoingSequenceNumber; int64_t outgoingSequenceNumber;
unsigned int mSampleRate; unsigned int iSampleRate;
unsigned int mChannels; unsigned int iChannels;
unsigned int mFrameSize; unsigned int iFrameSize;
unsigned int mAudioBufferSize; unsigned int iAudioBufferSize;
float *mFadeIn; float *fFadeIn;
float *mFadeOut; float *fFadeOut;
std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp; std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp;
}; };

View File

@ -8,14 +8,14 @@ mumlib::Audio::Audio(int sampleRate, int bitrate, int channels)
: logger(log4cpp::Category::getInstance("mumlib.Audio")), : logger(log4cpp::Category::getInstance("mumlib.Audio")),
opusDecoder(nullptr), opusDecoder(nullptr),
opusEncoder(nullptr), opusEncoder(nullptr),
outgoingSequenceNumber(0) { outgoingSequenceNumber(0),
iSampleRate(sampleRate),
iChannels(channels) {
int error, ret; int error, ret;
mSampleRate = sampleRate; iFrameSize = sampleRate / 100;
mChannels = channels; iAudioBufferSize = iFrameSize;
mFrameSize = sampleRate / 100; iAudioBufferSize *= 12;
mAudioBufferSize = mFrameSize;
mAudioBufferSize *= 12;
opusDecoder = opus_decoder_create(sampleRate, channels, &error); opusDecoder = opus_decoder_create(sampleRate, channels, &error);
if (error != OPUS_OK) { if (error != OPUS_OK) {
@ -55,17 +55,17 @@ mumlib::Audio::Audio(int sampleRate, int bitrate, int channels)
resetEncoder(); resetEncoder();
jbBuffer = jitter_buffer_init(mFrameSize); jbBuffer = jitter_buffer_init(iFrameSize);
int margin = 10 * mFrameSize; int margin = 10 * iFrameSize;
jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_SET_MARGIN, &margin); jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_SET_MARGIN, &margin);
mFadeIn = new float[mFrameSize]; fFadeIn = new float[iFrameSize];
mFadeOut = new float[mFrameSize]; fFadeOut = new float[iFrameSize];
// Sine function to represent fade in/out. Period is FRAME_SIZE. // Sine function to represent fade in/out. Period is FRAME_SIZE.
float mul = static_cast<float>(M_PI / 2.0 * static_cast<double>(mFrameSize)); float mul = static_cast<float>(M_PI / 2.0 * static_cast<double>(iFrameSize));
for(unsigned int i = 0; i < mFrameSize; i++) { for(unsigned int i = 0; i < iFrameSize; i++) {
mFadeIn[i] = mFadeOut[mFrameSize - 1 - 1] = sinf(static_cast<float>(i) * mul); fFadeIn[i] = fFadeOut[iFrameSize - 1 - 1] = sinf(static_cast<float>(i) * mul);
} }
} }
@ -80,8 +80,8 @@ mumlib::Audio::~Audio() {
jitter_buffer_destroy(jbBuffer); jitter_buffer_destroy(jbBuffer);
delete[] mFadeIn; delete[] fFadeIn;
delete[] mFadeOut; delete[] fFadeOut;
} }
void mumlib::Audio::setOpusEncoderBitrate(int bitrate) { void mumlib::Audio::setOpusEncoderBitrate(int bitrate) {
@ -111,17 +111,20 @@ void mumlib::Audio::addFrameToBuffer(uint8_t *inputBuffer, int inputLength, int
auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]); auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]);
int frame = opus_packet_get_nb_frames(packet, opusDataLength); int frame = opus_packet_get_nb_frames(packet, opusDataLength);
int samples = frame * opus_packet_get_samples_per_frame(packet, mSampleRate); int samples = frame * opus_packet_get_samples_per_frame(packet, iSampleRate);
int channel = opus_packet_get_nb_channels(packet);
if(not sequence) { if(not sequence) {
resetJitterBuffer(); resetJitterBuffer();
} }
logger.info("Opus packet, frame: %d, samples: %d, channel: %d", frame, samples, channel);
JitterBufferPacket jbPacket; JitterBufferPacket jbPacket;
jbPacket.data = reinterpret_cast<char *>(&inputBuffer[dataPointer]); jbPacket.data = reinterpret_cast<char *>(&inputBuffer[dataPointer]);
jbPacket.len = opusDataLength; jbPacket.len = opusDataLength;
jbPacket.span = samples; jbPacket.span = samples;
jbPacket.timestamp = mFrameSize * sequence; jbPacket.timestamp = iFrameSize * sequence;
jbPacket.user_data = lastPacket; jbPacket.user_data = lastPacket;
jitter_buffer_put(jbBuffer, &jbPacket); jitter_buffer_put(jbBuffer, &jbPacket);
@ -129,8 +132,12 @@ void mumlib::Audio::addFrameToBuffer(uint8_t *inputBuffer, int inputLength, int
std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pcmBufferSize) { std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pcmBufferSize) {
int avail = 0; int avail = 0;
int ts = jitter_buffer_get_pointer_timestamp(jbBuffer); spx_uint32_t remaining = 0;
jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_GET_AVAILABLE_COUNT, &avail); jitter_buffer_ctl(jbBuffer, JITTER_BUFFER_GET_AVAILABLE_COUNT, &avail);
jitter_buffer_remaining_span(jbBuffer, remaining);
int timestamp = jitter_buffer_get_pointer_timestamp(jbBuffer);
logger.warn("jbBufer, avail: %d, remain: %d, timestamp: %d", avail, remaining, timestamp);
char data[4096]; char data[4096];
JitterBufferPacket jbPacket; JitterBufferPacket jbPacket;
@ -142,10 +149,9 @@ std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pc
int outputSize; int outputSize;
spx_uint32_t lastPacket; spx_uint32_t lastPacket;
if(jitter_buffer_get(jbBuffer, &jbPacket, mFrameSize, &startofs) == JITTER_BUFFER_OK) { if(jitter_buffer_get(jbBuffer, &jbPacket, iFrameSize, &startofs) == JITTER_BUFFER_OK) {
opusDataLength = jbPacket.len; opusDataLength = jbPacket.len;
lastPacket = jbPacket.user_data; lastPacket = jbPacket.user_data;
} else { } else {
jitter_buffer_update_delay(jbBuffer, &jbPacket, NULL); jitter_buffer_update_delay(jbBuffer, &jbPacket, NULL);
} }
@ -162,16 +168,16 @@ std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pc
} }
if(outputSize < 0) { if(outputSize < 0) {
outputSize = mFrameSize; outputSize = iFrameSize;
memset(pcmBuffer, 0, mFrameSize * sizeof(float)); memset(pcmBuffer, 0, iFrameSize * sizeof(float));
} }
if(lastPacket) { if(lastPacket) {
for(unsigned int i = 0; i < mFrameSize; i++) for(unsigned int i = 0; i < iFrameSize; i++)
pcmBuffer[i] *= mFadeOut[i]; pcmBuffer[i] *= fFadeOut[i];
} }
for (int i = outputSize / mFrameSize; i > 0; --i) { for (int i = outputSize / iFrameSize; i > 0; --i) {
jitter_buffer_tick(jbBuffer); jitter_buffer_tick(jbBuffer);
} }
@ -181,7 +187,7 @@ std::pair<int, bool> mumlib::Audio::decodeOpusPayload(int16_t *pcmBuffer, int pc
return std::make_pair(outputSize, lastPacket); return std::make_pair(outputSize, lastPacket);
} }
void mumlib::Audio::mixAudio(uint8_t *inputBuffer, uint8_t *outputBuffer, int bufferOffset, int inputLength) { void mumlib::Audio::mixAudio(uint8_t *dest, uint8_t *src, int bufferOffset, int inputLength) {
for(int i = 0; i < inputLength; i++) { for(int i = 0; i < inputLength; i++) {
float mix = 0; float mix = 0;
@ -190,7 +196,7 @@ void mumlib::Audio::mixAudio(uint8_t *inputBuffer, uint8_t *outputBuffer, int bu
mix = 1; mix = 1;
else if(mix < -1) else if(mix < -1)
mix = -1; mix = -1;
outputBuffer[i + bufferOffset] = mix; dest[i + bufferOffset] = mix;
} }
} }
@ -222,7 +228,7 @@ std::pair<int, bool> mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer,
// Separate streams must be decoded with separate decoder states and can be decoded in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK defined. // Separate streams must be decoded with separate decoder states and can be decoded in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK defined.
auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]); auto *packet = reinterpret_cast<const unsigned char *>(&inputBuffer[dataPointer]);
int frame = opus_packet_get_nb_frames(packet, opusDataLength); int frame = opus_packet_get_nb_frames(packet, opusDataLength);
int samples = frame * opus_packet_get_samples_per_frame(packet, mSampleRate); int samples = frame * opus_packet_get_samples_per_frame(packet, iSampleRate);
int outputSize = opus_decode(opusDecoder, int outputSize = opus_decode(opusDecoder,
packet, packet,
opusDataLength, opusDataLength,
@ -280,7 +286,7 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
memcpy(outputBuffer, &header[0], header.size()); memcpy(outputBuffer, &header[0], header.size());
memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize); memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize);
int incrementNumber = 100 * inputLength / mSampleRate; int incrementNumber = 100 * inputLength / iSampleRate;
outgoingSequenceNumber += incrementNumber; outgoingSequenceNumber += incrementNumber;

View File

@ -34,7 +34,6 @@ namespace mumlib {
int sessionId = 0; int sessionId = 0;
int channelId = 0; int channelId = 0;
int64_t seq = 0; int64_t seq = 0;
mutex jitter_mutex;
std::vector<MumbleUser> listMumbleUser; std::vector<MumbleUser> listMumbleUser;
std::vector<MumbleChannel> listMumbleChannel; std::vector<MumbleChannel> listMumbleChannel;
@ -67,8 +66,6 @@ namespace mumlib {
auto incomingAudioPacket = audio.decodeIncomingAudioPacket(buffer, length); auto incomingAudioPacket = audio.decodeIncomingAudioPacket(buffer, length);
if (type == AudioPacketType::OPUS) { if (type == AudioPacketType::OPUS) {
// todo: multiple users speaking simultaneously (Issue #3)
// something weird while decoding the opus payload
int16_t pcmData[5000]; int16_t pcmData[5000];
audio.addFrameToBuffer(incomingAudioPacket.audioPayload, audio.addFrameToBuffer(incomingAudioPacket.audioPayload,
@ -84,13 +81,12 @@ namespace mumlib {
if(status.second) seq = 0; else seq++; if(status.second) seq = 0; else seq++;
// logger.warn("Decode audio: %d , seq %d", incomingAudioPacket.sessionId, seq);
callback.audio(incomingAudioPacket.target, callback.audio(incomingAudioPacket.target,
incomingAudioPacket.sessionId, incomingAudioPacket.sessionId,
incomingAudioPacket.sequenceNumber, incomingAudioPacket.sequenceNumber,
pcmData, pcmData,
status.first); status.first);
} else { } else {
logger.warn("Incoming audio packet doesn't contain Opus data, calling unsupportedAudio callback."); logger.warn("Incoming audio packet doesn't contain Opus data, calling unsupportedAudio callback.");
callback.unsupportedAudio(incomingAudioPacket.target, callback.unsupportedAudio(incomingAudioPacket.target,