ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error) { TOXAV_ERR_NEW rc = TOXAV_ERR_NEW_OK; ToxAV *av = NULL; if (tox == NULL) { rc = TOXAV_ERR_NEW_NULL; goto END; } if (((Messenger *)tox)->msi_packet) { rc = TOXAV_ERR_NEW_MULTIPLE; goto END; } av = calloc (sizeof(ToxAV), 1); if (av == NULL) { LOGGER_WARNING("Allocation failed!"); rc = TOXAV_ERR_NEW_MALLOC; goto END; } if (create_recursive_mutex(av->mutex) != 0) { LOGGER_WARNING("Mutex creation failed!"); rc = TOXAV_ERR_NEW_MALLOC; goto END; } av->m = (Messenger *)tox; av->msi = msi_new(av->m); if (av->msi == NULL) { pthread_mutex_destroy(av->mutex); rc = TOXAV_ERR_NEW_MALLOC; goto END; } av->interval = 200; av->msi->av = av; msi_register_callback(av->msi, callback_invite, msi_OnInvite); msi_register_callback(av->msi, callback_start, msi_OnStart); msi_register_callback(av->msi, callback_end, msi_OnEnd); msi_register_callback(av->msi, callback_error, msi_OnError); msi_register_callback(av->msi, callback_error, msi_OnPeerTimeout); msi_register_callback(av->msi, callback_capabilites, msi_OnCapabilities); END: if (error) *error = rc; if (rc != TOXAV_ERR_NEW_OK) { free(av); av = NULL; } return av; }
bool SDLPlatform::_initialize() { m_touchpad = false; if( SDL_Init(SDL_INIT_EVERYTHING) < 0 ) { LOGGER_CRITICAL(m_serviceProvider)("SDL initialization failed"); return false; } const Char* sdlPlatform = SDL_GetPlatform(); const int sdlRam = SDL_GetSystemRAM(); m_platformName = Helper::stringizeString(m_serviceProvider, sdlPlatform); LOGGER_WARNING(m_serviceProvider)("Device info:" ); LOGGER_WARNING(m_serviceProvider)("Platform: %s" , sdlPlatform ); LOGGER_WARNING(m_serviceProvider)("RAM: %d MB" , sdlRam ); m_sdlInput = new SDLInput(); m_sdlInput->setServiceProvider(m_serviceProvider); if( !m_sdlInput->initialize() ) { return false; } return true; }
/** * @brief Encode audio frame * * @param av Handler * @param dest dest * @param dest_max Max dest size * @param frame The frame * @param frame_size The frame size * @return int * @retval ToxAvError On error. * @retval >0 On success */ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, const int16_t *frame, int frame_size) { if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; pthread_mutex_lock(&call->mutex); if (!call->call_active) { pthread_mutex_unlock(&call->mutex); LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max); pthread_mutex_unlock(&call->mutex); if (rc < 0) { LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); return ErrorInternal; } return rc; }
/** * @brief Receive decoded audio frame. * * @param av Handler. * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes * and corresponds to one sample of audio.) * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels). * Make sure it has enough space for frame_size frames/samples. * @return int * @retval >=0 Size of received data in frames/samples. * @retval ToxAvError On error. */ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest ) { if ( !dest ) return ErrorInternal; if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; uint8_t packet [RTP_PAYLOAD_SIZE]; int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet); if ( recved_size == ErrorAudioPacketLost ) { int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); if ( dec_size < 0 ) { LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); return ErrorInternal; } else return dec_size; } else if ( recved_size ) { int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); if ( dec_size < 0 ) { LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); return ErrorInternal; } else return dec_size; } else { return 0; /* Nothing received */ } }
/** * Callback for networking core. */ int rtp_handle_packet ( void *object, const uint8_t *data, uint32_t length ) { RTPSession *session = object; RTPMessage *msg; if ( !session || length < 13 ) { /* 12 is the minimum length for rtp + desc. byte */ LOGGER_WARNING("No session or invalid length of received buffer!"); return -1; } msg = msg_parse ( data + 1, length - 1 ); if ( !msg ) { LOGGER_WARNING("Could not parse message!"); return -1; } /* Check if message came in late */ if ( check_late_message(session, msg) < 0 ) { /* Not late */ session->rsequnum = msg->header->sequnum; session->timestamp = msg->header->timestamp; } queue_message(session, msg); return 0; }
TagLib::ByteVector TagLib::EncodeBase64(const TagLib::ByteVector& input) { ByteVector result; CFErrorRef error; SFB::SecTransform encoder = SecEncodeTransformCreate(kSecBase64Encoding, &error); if(nullptr == encoder) { LOGGER_WARNING("org.sbooth.AudioEngine", "SecEncodeTransformCreate failed: " << error); return TagLib::ByteVector::null; } SFB::CFData sourceData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)input.data(), (CFIndex)input.size(), kCFAllocatorNull); if(!sourceData) return TagLib::ByteVector::null; if(!SecTransformSetAttribute(encoder, kSecTransformInputAttributeName, sourceData, &error)) { LOGGER_WARNING("org.sbooth.AudioEngine", "SecTransformSetAttribute failed: " << error); return TagLib::ByteVector::null; } SFB::CFData encodedData = (CFDataRef)SecTransformExecute(encoder, &error); if(!encodedData) { LOGGER_WARNING("org.sbooth.AudioEngine", "SecTransformExecute failed: " << error); return TagLib::ByteVector::null; } result.setData((const char *)CFDataGetBytePtr((CFDataRef)encodedData), (TagLib::uint)CFDataGetLength((CFDataRef)encodedData)); return result; }
int ac_queue_message(void *acp, struct RTPMessage *msg) { if (!acp || !msg) { return -1; } ACSession *ac = (ACSession *)acp; if ((msg->header.pt & 0x7f) == (rtp_TypeAudio + 2) % 128) { LOGGER_WARNING(ac->log, "Got dummy!"); free(msg); return 0; } if ((msg->header.pt & 0x7f) != rtp_TypeAudio % 128) { LOGGER_WARNING(ac->log, "Invalid payload type!"); free(msg); return -1; } pthread_mutex_lock(ac->queue_mutex); int rc = jbuf_write(ac->log, (struct JitterBuffer *)ac->j_buf, msg); pthread_mutex_unlock(ac->queue_mutex); if (rc == -1) { LOGGER_WARNING(ac->log, "Could not queue the message!"); free(msg); return -1; } return 0; }
/** * @brief Send audio frame. * * @param av Handler. * @param data The audio data encoded with toxav_prepare_audio_frame(). * @param size Its size in number of bytes. * @return int * @retval 0 Success. * @retval ToxAvError On error. */ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *data, unsigned int size) { if (size > MAX_CRYPTO_DATA_SIZE) return ErrorInternal; if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; pthread_mutex_lock(&call->mutex); if (!call->call_active) { pthread_mutex_unlock(&call->mutex); LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, data, size); pthread_mutex_unlock(&call->mutex); return rc; }
void handle_push(MSICall *call, const MSIMessage *msg) { assert(call); LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'push' friend: %d", call->session, call->friend_number); if (!msg->capabilities.exists) { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'push'"); call->error = msi_EInvalidMessage; goto FAILURE; } switch (call->state) { case msi_CallActive: { /* Only act if capabilities changed */ if (call->peer_capabilities != msg->capabilities.value) { LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value); call->peer_capabilities = msg->capabilities.value; if (invoke_callback(call, msi_OnCapabilities) == -1) { goto FAILURE; } } } break; case msi_CallRequesting: { LOGGER_INFO(call->session->messenger->log, "Friend answered our call"); /* Call started */ call->peer_capabilities = msg->capabilities.value; call->state = msi_CallActive; if (invoke_callback(call, msi_OnStart) == -1) { goto FAILURE; } } break; /* Pushes during initialization state are ignored */ case msi_CallInactive: // fall-through case msi_CallRequested: { LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push"); } break; } return; FAILURE: send_error(call->session->messenger, call->friend_number, call->error); kill_call(call); }
SFB::Audio::Metadata::unique_ptr SFB::Audio::Metadata::CreateMetadataForURL(CFURLRef url, CFErrorRef *error) { if(nullptr == url) return nullptr; // If this is a file URL, use the extension-based resolvers SFB::CFString scheme = CFURLCopyScheme(url); // If there is no scheme the URL is invalid if(!scheme) { if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, EINVAL, nullptr); return nullptr; } if(kCFCompareEqualTo == CFStringCompare(CFSTR("file"), scheme, kCFCompareCaseInsensitive)) { // Verify the file exists SInt32 errorCode = noErr; SFB::CFBoolean fileExists = (CFBooleanRef)CFURLCreatePropertyFromResource(kCFAllocatorDefault, url, kCFURLFileExists, &errorCode); if(fileExists) { if(CFBooleanGetValue(fileExists)) { SFB::CFString pathExtension = CFURLCopyPathExtension(url); if(pathExtension) { // Some extensions (.oga for example) support multiple audio codecs (Vorbis, FLAC, Speex) for(auto subclassInfo : sRegisteredSubclasses) { if(subclassInfo.mHandlesFilesWithExtension(pathExtension)) { unique_ptr metadata(subclassInfo.mCreateMetadata(url)); if(metadata->ReadMetadata(error)) return metadata; } } } } else { LOGGER_WARNING("org.sbooth.AudioEngine.Metadata", "The requested URL doesn't exist"); if(error) { SFB::CFString description = CFCopyLocalizedString(CFSTR("The file “%@” does not exist."), ""); SFB::CFString failureReason = CFCopyLocalizedString(CFSTR("File not found"), ""); SFB::CFString recoverySuggestion = CFCopyLocalizedString(CFSTR("The file may exist on removable media or may have been deleted."), ""); *error = CreateErrorForURL(Metadata::ErrorDomain, Metadata::InputOutputError, description, url, failureReason, recoverySuggestion); } } } else LOGGER_WARNING("org.sbooth.AudioEngine.Metadata", "CFURLCreatePropertyFromResource failed: " << errorCode); } return nullptr; }
/** * @brief Encode video frame * * @param av Handler * @param dest Where to * @param dest_max Max size * @param input What to encode * @return int * @retval ToxAvError On error. * @retval >0 On success */ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) { if (cii(call_index, av->msi_session)) { LOGGER_WARNING("Invalid call index: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; pthread_mutex_lock(&call->mutex); if (!call->call_active) { pthread_mutex_unlock(&call->mutex); LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0) { pthread_mutex_unlock(&call->mutex); return ErrorInternal; } int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); if ( rc != VPX_CODEC_OK) { LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); pthread_mutex_unlock(&call->mutex); return ErrorInternal; } ++call->cs->frame_counter; vpx_codec_iter_t iter = NULL; const vpx_codec_cx_pkt_t *pkt; int copied = 0; while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { if ( copied + pkt->data.frame.sz > dest_max ) { pthread_mutex_unlock(&call->mutex); return ErrorPacketTooLarge; } memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); copied += pkt->data.frame.sz; } } pthread_mutex_unlock(&call->mutex); return copied; }
RTPSession *rtp_new ( int payload_type, Messenger *messenger, int friend_num ) { RTPSession *retu = calloc(1, sizeof(RTPSession)); if ( !retu ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); return NULL; } if ( -1 == custom_lossy_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, retu)) { LOGGER_ERROR("Error setting custom register handler for rtp session"); free(retu); return NULL; } LOGGER_DEBUG("Registered packet handler: pt: %d; fid: %d", payload_type, friend_num); retu->version = RTP_VERSION; /* It's always 2 */ retu->padding = 0; /* If some additional data is needed about the packet */ retu->extension = 0; /* If extension to header is needed */ retu->cc = 1; /* Amount of contributors */ retu->csrc = NULL; /* Container */ retu->ssrc = random_int(); retu->marker = 0; retu->payload_type = payload_type % 128; retu->dest = friend_num; retu->rsequnum = retu->sequnum = 0; retu->ext_header = NULL; /* When needed allocate */ if ( !(retu->csrc = calloc(1, sizeof (uint32_t))) ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); free(retu); return NULL; } retu->csrc[0] = retu->ssrc; /* Set my ssrc to the list receive */ /* Also set payload type as prefix */ retu->prefix = payload_type; /* * */ return retu; }
SInt64 SFB::Audio::DSFDecoder::_SeekToFrame(SInt64 frame) { // Round down to nearest multiple of 8 frames frame = (frame / 8) * 8; // Seek to the start of the block containing frame auto blockSizePerChannelInFrames = mFormat.ByteCountToFrameCount(mBlockByteSizePerChannel); auto blockNumber = (size_t)frame / blockSizePerChannelInFrames; auto blockOffset = blockNumber * mBlockByteSizePerChannel * mFormat.mChannelsPerFrame; if(!GetInputSource().SeekToOffset(mAudioOffset + (SInt64)blockOffset)) { LOGGER_WARNING("org.sbooth.AudioEngine.Decoder.DSF", "_SeekToFrame() failed for offset: " << mAudioOffset + (SInt64)blockOffset); return -1; } if(!ReadAndDeinterleaveDSDBlock()) return -1; // Skip to the specified frame UInt32 framesToSkip = (UInt32)frame % blockSizePerChannelInFrames; UInt32 framesInBuffer = (UInt32)mFormat.ByteCountToFrameCount(mBufferList->mBuffers[0].mDataByteSize); // Copy data from the buffer to output for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) { uint8_t *dst = (uint8_t *)mBufferList->mBuffers[i].mData; memmove(dst, dst + mFormat.FrameCountToByteCount(framesToSkip), mFormat.FrameCountToByteCount(framesInBuffer - framesToSkip)); mBufferList->mBuffers[i].mDataByteSize -= (UInt32)mFormat.FrameCountToByteCount(framesToSkip); } mCurrentFrame = frame; return _GetCurrentFrame(); }
int invoke_callback(MSICall *call, MSICallbackID cb) { assert(call); if (call->session->callbacks[cb]) { LOGGER_DEBUG(call->session->messenger->log, "Invoking callback function: %d", cb); if (call->session->callbacks[cb](call->session->av, call) != 0) { LOGGER_WARNING(call->session->messenger->log, "Callback state handling failed, sending error"); goto FAILURE; } return 0; } FAILURE: /* If no callback present or error happened while handling, * an error message will be sent to friend */ if (call->error == msi_ENone) { call->error = msi_EHandle; } return -1; }
/** * Builds header from control session values. */ RTPHeader *build_header ( RTPSession *session ) { RTPHeader *retu = calloc ( 1, sizeof (RTPHeader) ); if ( !retu ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); return NULL; } ADD_FLAG_VERSION ( retu, session->version ); ADD_FLAG_PADDING ( retu, session->padding ); ADD_FLAG_EXTENSION ( retu, session->extension ); ADD_FLAG_CSRCC ( retu, session->cc ); ADD_SETTING_MARKER ( retu, session->marker ); ADD_SETTING_PAYLOAD ( retu, session->payload_type ); retu->sequnum = session->sequnum; retu->timestamp = current_time_monotonic(); /* milliseconds */ retu->ssrc = session->ssrc; int i; for ( i = 0; i < session->cc; i++ ) retu->csrc[i] = session->csrc[i]; retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 ); return retu; }
bool MemoryMappedFileInputSource::Close(CFErrorRef *error) { if(!IsOpen()) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource.MemoryMappedFile", "Close() called on an InputSource that hasn't been opened"); return true; } memset(&mFilestats, 0, sizeof(mFilestats)); if(nullptr != mMemory) { int result = munmap(mMemory, mFilestats.st_size); mMemory = nullptr; mCurrentPosition = nullptr; if(-1 == result) { if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, errno, nullptr); return false; } } mIsOpen = false; return true; }
bool HTTPInputSource::Open(CFErrorRef *error) { if(IsOpen()) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource.HTTP", "Open() called on an InputSource that is already open"); return true; } // Set up the HTTP request mRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), mURL, kCFHTTPVersion1_1); if(NULL == mRequest) { if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL); return false; } CFHTTPMessageSetHeaderFieldValue(mRequest, CFSTR("User-Agent"), CFSTR("SFBAudioEngine")); // Seek support if(0 < mDesiredOffset) { CFStringRef byteRange = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("bytes=%ld-"), mDesiredOffset); CFHTTPMessageSetHeaderFieldValue(mRequest, CFSTR("Range"), byteRange); CFRelease(byteRange), byteRange = NULL; } mReadStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, mRequest, NULL); if(NULL == mReadStream) { CFRelease(mRequest), mRequest = NULL; if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL); return false; } // Start the HTTP connection CFStreamClientContext myContext = { 0, this, NULL, NULL, NULL }; CFOptionFlags clientFlags = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; if(!CFReadStreamSetClient(mReadStream, clientFlags, myCFReadStreamClientCallBack, &myContext)) { CFRelease(mRequest), mRequest = NULL; CFRelease(mReadStream), mReadStream = NULL; if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL); return false; } CFReadStreamScheduleWithRunLoop(mReadStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); if(!CFReadStreamOpen(mReadStream)) { CFRelease(mRequest), mRequest = NULL; CFRelease(mReadStream), mReadStream = NULL; if(error) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, ENOMEM, NULL); return false; } while(NULL == mResponseHeaders) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true); mIsOpen = true; return true; }
int callback_invite(void *toxav_inst, MSICall *call) { ToxAV *toxav = toxav_inst; pthread_mutex_lock(toxav->mutex); ToxAVCall *av_call = call_new(toxav, call->friend_number, NULL); if (av_call == NULL) { LOGGER_WARNING("Failed to initialize call..."); pthread_mutex_unlock(toxav->mutex); return -1; } call->av_call = av_call; av_call->msi_call = call; if (toxav->ccb.first) toxav->ccb.first(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, call->peer_capabilities & msi_CapSVideo, toxav->ccb.second); else { /* No handler to capture the call request, send failure */ pthread_mutex_unlock(toxav->mutex); return -1; } pthread_mutex_unlock(toxav->mutex); return 0; }
ResourceReferencePtr ResourceManager::getResourceReference( const ConstString & _name ) const { const ResourceEntry * entry = this->findResource_( _name ); if( entry == nullptr ) { LOGGER_WARNING(m_serviceProvider)("ResourceManager::getResourceReference: resource '%s' does not exist" , _name.c_str() ); return nullptr; } if( entry->isLocked == true ) { LOGGER_ERROR(m_serviceProvider)("ResourceManager::getResourceReference: resource '%s' is LOCK!" , _name.c_str() ); return nullptr; } const ResourceReferencePtr & resource = entry->resource; return resource; }
/** * Allocate message and store data there */ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t length ) { if ( !session ) { LOGGER_WARNING("No session!"); return NULL; } uint8_t *from_pos; RTPMessage *retu = calloc(1, sizeof (RTPMessage)); if ( !retu ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); return NULL; } /* Sets header values and copies the extension header in retu */ retu->header = build_header ( session ); /* It allocates memory and all */ retu->ext_header = session->ext_header; uint32_t total_length = length + retu->header->length + 1; retu->data[0] = session->prefix; if ( retu->ext_header ) { total_length += ( 4 /* Minimum ext header len */ + retu->ext_header->length * size_32 ); from_pos = add_header ( retu->header, retu->data + 1 ); from_pos = add_ext_header ( retu->ext_header, from_pos + 1 ); } else { from_pos = add_header ( retu->header, retu->data + 1 ); } /* * Parses the extension header into the message * Of course if any */ /* Appends data on to retu->data */ memcpy ( from_pos, data, length ); retu->length = total_length; retu->next = NULL; return retu; }
bool SoundConverterFFMPEGToOGG::convert() { FileGroupInterfacePtr fileGroup; if( FILE_SERVICE(m_serviceProvider)->hasFileGroup( m_options.pakName, &fileGroup ) == false ) { LOGGER_ERROR(m_serviceProvider)("SoundConverterFFMPEGToOGG::convert_: not found file group '%s'" , m_options.pakName.c_str() ); return false; } const ConstString & pakPath = fileGroup->getPath(); String full_input = pakPath.c_str(); full_input += m_options.inputFileName.c_str(); String full_output = pakPath.c_str(); full_output += m_options.outputFileName.c_str(); WString unicode_input; if( Helper::utf8ToUnicode( m_serviceProvider, full_input, unicode_input ) == false ) { LOGGER_ERROR(m_serviceProvider)("SoundConverterFFMPEGToOGG::convert_: invalid convert input utf8 to unicode %s" , full_input.c_str() ); return false; } WString unicode_output; if( Helper::utf8ToUnicode( m_serviceProvider, full_output, unicode_output ) == false ) { LOGGER_ERROR(m_serviceProvider)("SoundConverterFFMPEGToOGG::convert_: invalid convert output utf8 to unicode %s" , full_output.c_str() ); return false; } WString buffer = L"ffmpeg.exe -loglevel error -y -threads 4 -i \"" + unicode_input + L"\" -map_metadata -1 -ac 2 -ar 44100 -acodec libvorbis -aq 100 \"" + unicode_output + L"\""; LOGGER_WARNING(m_serviceProvider)( "SoundDecoderConverterFFMPEGToOGG:: converting file '%ls' to '%ls'" , unicode_input.c_str() , unicode_output.c_str() ); if( WINDOWSLAYER_SERVICE(m_serviceProvider) ->cmd( buffer ) == false ) { LOGGER_ERROR(m_serviceProvider)("SoundConverterFFMPEGToOGG::convert_: invalid convert:" ); return false; } return true; }
bool SFB::InputSource::SeekToOffset(SInt64 offset) { if(!IsOpen() || 0 > offset) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource", "Close() called on an InputSource that hasn't been opened"); return false; } return _SeekToOffset(offset); }
bool SFB::InputSource::SupportsSeeking() const { if(!IsOpen()) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource", "SupportsSeeking() called on an InputSource that hasn't been opened"); return false; } return _SupportsSeeking(); }
SInt64 SFB::InputSource::GetLength() const { if(!IsOpen()) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource", "GetLength() called on an InputSource that hasn't been opened"); return 0; } return _GetLength(); }
bool SFB::InputSource::AtEOF() const { if(!IsOpen()) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource", "AtEOF() called on an InputSource that hasn't been opened"); return true; } return _AtEOF(); }
SInt64 SFB::InputSource::Read(void *buffer, SInt64 byteCount) { if(!IsOpen() || nullptr == buffer || 0 > byteCount) { LOGGER_WARNING("org.sbooth.AudioEngine.InputSource", "Read() called on an InputSource that hasn't been opened"); return -1; } return _Read(buffer, byteCount); }
/** * Extracts external header from payload. Must be called AFTER extract_header()! */ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length ) { const uint8_t *it = payload; RTPExtHeader *retu = calloc(1, sizeof (RTPExtHeader)); if ( !retu ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); return NULL; } uint16_t ext_length; memcpy(&ext_length, it, sizeof(ext_length)); ext_length = ntohs(ext_length); it += 2; if ( length < ( ext_length * sizeof(uint32_t) ) ) { LOGGER_WARNING("Length invalid!"); free(retu); return NULL; } retu->length = ext_length; memcpy(&retu->type, it, sizeof(retu->type)); retu->type = ntohs(retu->type); it += 2; if ( !(retu->table = calloc(ext_length, sizeof (uint32_t))) ) { LOGGER_WARNING("Alloc failed! Program might misbehave!"); free(retu); return NULL; } uint16_t x; for ( x = 0; x < ext_length; x++ ) { it += 4; memcpy(&(retu->table[x]), it, sizeof(retu->table[x])); retu->table[x] = ntohl(retu->table[x]); } return retu; }
/** * Parses data into RTPMessage struct. Stores headers separately from the payload data * and so the length variable is set accordingly. */ RTPMessage *msg_parse ( const uint8_t *data, int length ) { RTPMessage *retu = calloc(1, sizeof (RTPMessage)); retu->header = extract_header ( data, length ); /* It allocates memory and all */ if ( !retu->header ) { LOGGER_WARNING("Header failed to extract!"); free(retu); return NULL; } uint16_t from_pos = retu->header->length; retu->length = length - from_pos; if ( GET_FLAG_EXTENSION ( retu->header ) ) { retu->ext_header = extract_ext_header ( data + from_pos, length ); if ( retu->ext_header ) { retu->length -= ( 4 /* Minimum ext header len */ + retu->ext_header->length * size_32 ); from_pos += ( 4 /* Minimum ext header len */ + retu->ext_header->length * size_32 ); } else { /* Error */ LOGGER_WARNING("Ext Header failed to extract!"); rtp_free_msg(NULL, retu); return NULL; } } else { retu->ext_header = NULL; } if ( length - from_pos <= MAX_RTP_SIZE ) memcpy ( retu->data, data + from_pos, length - from_pos ); else { LOGGER_WARNING("Invalid length!"); rtp_free_msg(NULL, retu); return NULL; } retu->next = NULL; return retu; }
/** * @brief Send audio frame. * * @param av Handler. * @param frame The frame (raw 16 bit signed pcm with AUDIO_CHANNELS channels audio.) * @param frame_size Its size in number of frames/samples (one frame/sample is 16 bits or 2 bytes) * frame size should be AUDIO_FRAME_SIZE. * @return int * @retval 0 Success. * @retval ToxAvError On error. */ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) { if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); }
bool Semaphore::TimedWait(mach_timespec_t duration) { kern_return_t result = semaphore_timedwait(mSemaphore, duration); if(KERN_SUCCESS != result && KERN_OPERATION_TIMED_OUT != result) { LOGGER_WARNING("org.sbooth.AudioEngine.Semaphore", "Semaphore couldn't timedwait: " << mach_error_string(result)); return false; } return true; }