static void * SILKDecoderCreate (const struct PluginCodec_Definition * codec) { SKP_int16 ret; SKP_int32 decSizeBytes; struct SILKDecoderControl * ctxt; /* Create decoder */ ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if( ret ) { printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); } ctxt = (struct SILKDecoderControl*)malloc(1*(sizeof(struct SILKDecoderControl)+decSizeBytes)); ctxt->context = malloc( decSizeBytes ); ctxt->mutex = new CriticalSection(); ctxt->control.framesPerPacket = codec->parm.audio.maxFramesPerPacket; ctxt->control.API_sampleRate = codec->sampleRate; ctxt->control.frameSize = codec->parm.audio.samplesPerFrame; ctxt->control.inBandFECOffset = 0; ctxt->control.moreInternalDecoderFrames = 0; ret = SKP_Silk_SDK_InitDecoder( ctxt->context ); if( ret ) { printf( "\nSKP_Silk_InitDecoder returned %d", ret ); } return ctxt; }
JNIEXPORT jint JNICALL Java_org_sipdroid_codecs_SILK8_open (JNIEnv *env, jobject obj, jint compression) { int ret; if (codec_open++ != 0) return (jint)0; /* Set the samplingrate that is requested for the output */ DecControl.sampleRate = 8000; /* Create decoder */ ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if( ret ) { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); } #ifdef DEBUG_SILK8 __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "### INIT Decoder decSizeBytes = %d\n", decSizeBytes); #endif psDec = malloc( decSizeBytes ); /* Reset decoder */ ret = SKP_Silk_SDK_InitDecoder( psDec ); if( ret ) { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret ); } /* Create Encoder */ ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes ); if( ret ) { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret ); } #ifdef DEBUG_SILK8 __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "### INIT Encoder encSizeBytes = %d\n", encSizeBytes); #endif psEnc = malloc( encSizeBytes ); /* Reset Encoder */ ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl ); if( ret ) { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret ); } /* Set Encoder parameters */ encControl.sampleRate = fs_kHz * 1000; encControl.packetSize = packetSize_ms * fs_kHz; encControl.packetLossPercentage = packetLoss_perc; encControl.useInBandFEC = INBandFec_enabled; encControl.useDTX = DTX_enabled; encControl.complexity = compression; encControl.bitRate = targetRate_bps; return (jint)0; }
//initialize SILK codec //sets number of 20mS(160 samples) frames per packet (1-5) void SILK8_open(int fpp) { //set number of 20 mS (160 samoles) frames per packet (1-5) if ((fpp <= MAX_INPUT_FRAMES) && (fpp > 0)) skp_frames_pp = fpp; packetSize_ms = skp_frames_pp * 20; // Set the samplingrate that is requested for the output DecControl.sampleRate = 8000; // Create decoder SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes); psDec = malloc(decSizeBytes); // Reset decoder SKP_Silk_SDK_InitDecoder(psDec); // Create Encoder SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes); psEnc = malloc(encSizeBytes); // Reset Encoder SKP_Silk_SDK_InitEncoder(psEnc, &encControl); // Set Encoder parameters encControl.sampleRate = 8000; encControl.packetSize = packetSize_ms * 8; //samples per packet encControl.packetLossPercentage = packetLoss_perc; encControl.useInBandFEC = INBandFec_enabled; encControl.useDTX = DTX_enabled; encControl.complexity = compression; encControl.bitRate = targetRate_bps; }
static int create_SILK_decoder(SILK_state* st, unsigned int rtp_Hz) { SKP_int32 ret, decSizeBytes; /* Set the samplingrate that is requested for the output */ st->decControl.API_sampleRate = rtp_Hz; /* Initialize to one frame per packet, for proper concealment before first packet arrives */ st->decControl.framesPerPacket = 1; /* Create decoder */ ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if( ret ) { ERROR( "SKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); return ret; } st->psDec = malloc( decSizeBytes ); if(st->psDec == NULL) { ERROR( "could not allocate SILK decoder state" ); return -1; } /* Reset decoder */ ret = SKP_Silk_SDK_InitDecoder( st->psDec ); if( ret ) { ERROR( "SKP_Silk_InitDecoder returned %d", ret ); return ret; } return 0; }
virtual bool Construct() { SKP_int32 sizeBytes = 0; if (SKP_Silk_SDK_Get_Decoder_Size(&sizeBytes) != 0) return false; m_state = malloc(sizeBytes); if (m_state == NULL) return false; return SKP_Silk_SDK_InitDecoder(m_state) == 0; }
bool VoiceEncoder_Silk::Init(int quality) { m_targetRate_bps = 25000; m_packetLoss_perc = 0; int encSizeBytes; SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes); m_pEncoder = malloc(encSizeBytes); SKP_Silk_SDK_InitEncoder(m_pEncoder, &this->m_encControl); int decSizeBytes; SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes); m_pDecoder = malloc(decSizeBytes); SKP_Silk_SDK_InitDecoder(m_pDecoder); return true; }
static int decode_update(struct audec_state **adsp, const struct aucodec *ac, const char *fmtp) { struct audec_state *st; int ret, err = 0; int32_t dec_size; (void)fmtp; if (*adsp) return 0; ret = SKP_Silk_SDK_Get_Decoder_Size(&dec_size); if (ret || dec_size <= 0) return EINVAL; st = mem_alloc(sizeof(*st), decode_destructor); if (!st) return ENOMEM; st->dec = mem_alloc(dec_size, NULL); if (!st->dec) { err = ENOMEM; goto out; } ret = SKP_Silk_SDK_InitDecoder(st->dec); if (ret) { err = EPROTO; goto out; } st->decControl.API_sampleRate = ac->srate; out: if (err) mem_deref(st); else *adsp = st; return err; }
/* * Open codec. */ static pj_status_t silk_codec_open(pjmedia_codec *codec, pjmedia_codec_param *attr ) { silk_private *silk; silk_param *sp; SKP_int st_size, err; pj_bool_t enc_use_fec; unsigned enc_bitrate, i; PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL); silk = (silk_private*)codec->codec_data; sp = &silk_factory.silk_param[silk->mode]; /* Already opened? */ if (silk->enc_ready || silk->dec_ready) return PJ_SUCCESS; /* Allocate and initialize encoder */ err = SKP_Silk_SDK_Get_Encoder_Size(&st_size); if (err) { PJ_LOG(3,(THIS_FILE, "Failed to get encoder state size (err=%d)", err)); return PJMEDIA_CODEC_EFAILED; } silk->enc_st = pj_pool_zalloc(silk->pool, st_size); err = SKP_Silk_SDK_InitEncoder(silk->enc_st, &silk->enc_ctl); if (err) { PJ_LOG(3,(THIS_FILE, "Failed to init encoder (err=%d)", err)); return PJMEDIA_CODEC_EFAILED; } /* Check fmtp params */ enc_use_fec = PJ_TRUE; enc_bitrate = sp->bitrate; for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { pjmedia_codec_fmtp *fmtp = &attr->setting.enc_fmtp; const pj_str_t STR_USEINBANDFEC = {"useinbandfec", 12}; const pj_str_t STR_MAXAVERAGEBITRATE = {"maxaveragebitrate", 17}; if (!pj_stricmp(&fmtp->param[i].name, &STR_USEINBANDFEC)) { enc_use_fec = pj_strtoul(&fmtp->param[i].val) != 0; } else if (!pj_stricmp(&fmtp->param[i].name, &STR_MAXAVERAGEBITRATE)) { enc_bitrate = pj_strtoul(&fmtp->param[i].val); if (enc_bitrate > sp->max_bitrate) { enc_bitrate = sp->max_bitrate; } } } /* Setup encoder control for encoding process */ silk->enc_ready = PJ_TRUE; silk->samples_per_frame = FRAME_LENGTH_MS * attr->info.clock_rate / 1000; silk->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8; silk->enc_ctl.API_sampleRate = attr->info.clock_rate; silk->enc_ctl.maxInternalSampleRate = attr->info.clock_rate; silk->enc_ctl.packetSize = attr->setting.frm_per_pkt * silk->samples_per_frame; /* For useInBandFEC setting to be useful, we need to set * packetLossPercentage greater than LBRR_LOSS_THRES (1) */ silk->enc_ctl.packetLossPercentage = SILK_ENC_CTL_PACKET_LOSS_PCT; silk->enc_ctl.useInBandFEC = enc_use_fec; silk->enc_ctl.useDTX = attr->setting.vad; silk->enc_ctl.complexity = sp->complexity; silk->enc_ctl.bitRate = enc_bitrate; /* Allocate and initialize decoder */ err = SKP_Silk_SDK_Get_Decoder_Size(&st_size); if (err) { PJ_LOG(3,(THIS_FILE, "Failed to get decoder state size (err=%d)", err)); return PJMEDIA_CODEC_EFAILED; } silk->dec_st = pj_pool_zalloc(silk->pool, st_size); err = SKP_Silk_SDK_InitDecoder(silk->dec_st); if (err) { PJ_LOG(3,(THIS_FILE, "Failed to init decoder (err=%d)", err)); return PJMEDIA_CODEC_EFAILED; } /* Setup decoder control for decoding process */ silk->dec_ctl.API_sampleRate = attr->info.clock_rate; silk->dec_ctl.framesPerPacket = 1; /* for proper PLC at start */ silk->dec_ready = PJ_TRUE; silk->dec_buf_sz = attr->info.clock_rate * attr->info.channel_cnt * attr->info.frm_ptime / 1000 * silk->pcm_bytes_per_sample; /* Inform the stream to prepare a larger buffer since we cannot parse * SILK packets and split it into individual frames. */ attr->info.max_rx_frame_size = attr->info.max_bps * attr->info.frm_ptime / 8 / 1000; if ((attr->info.max_bps * attr->info.frm_ptime) % 8000 != 0) { ++attr->info.max_rx_frame_size; } attr->info.max_rx_frame_size *= SILK_MAX_FRAMES_PER_PACKET; return PJ_SUCCESS; }
static switch_status_t switch_silk_init(switch_codec_t *codec, switch_codec_flag_t freeswitch_flags, const switch_codec_settings_t *codec_settings) { struct silk_context *context = NULL; switch_codec_fmtp_t codec_fmtp; silk_codec_settings_t silk_codec_settings; SKP_int32 encSizeBytes; SKP_int32 decSizeBytes; int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE); int decoding = (freeswitch_flags & SWITCH_CODEC_FLAG_DECODE); if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); codec_fmtp.private_info = &silk_codec_settings; switch_silk_fmtp_parse(codec->fmtp_in, &codec_fmtp); codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d", silk_codec_settings.useinbandfec ? "1" : "0", silk_codec_settings.usedtx ? "1" : "0", silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second); if (encoding) { if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) { return SWITCH_STATUS_FALSE; } context->enc_state = switch_core_alloc(codec->memory_pool, encSizeBytes); if (SKP_Silk_SDK_InitEncoder(context->enc_state, &context->encoder_object)) { return SWITCH_STATUS_FALSE; } context->encoder_object.API_sampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.maxInternalSampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.packetSize = codec->implementation->samples_per_packet; context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec; context->encoder_object.complexity = 0; context->encoder_object.bitRate = silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second; context->encoder_object.useDTX = silk_codec_settings.usedtx; context->encoder_object.packetLossPercentage = silk_codec_settings.plpct; } if (decoding) { if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) { return SWITCH_STATUS_FALSE; } context->dec_state = switch_core_alloc(codec->memory_pool, decSizeBytes); if (SKP_Silk_SDK_InitDecoder(context->dec_state)) { return SWITCH_STATUS_FALSE; } context->decoder_object.API_sampleRate = codec->implementation->actual_samples_per_second; } codec->private_info = context; return SWITCH_STATUS_SUCCESS; }
int main( int argc, char* argv[] ) { unsigned long tottime, starttime; double filetime; size_t counter; SKP_int32 args, totPackets, i, k; SKP_int16 ret, len, tot_len; SKP_int16 nBytes; SKP_uint8 payload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ]; SKP_uint8 *payloadEnd = NULL, *payloadToDec = NULL; SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ], *payloadPtr; SKP_int16 nBytesFEC; SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes; SKP_int16 out[ ( ( FRAME_LENGTH_MS * MAX_API_FS_KHZ ) << 1 ) * MAX_INPUT_FRAMES ], *outPtr; char speechOutFileName[ 150 ], bitInFileName[ 150 ]; FILE *bitInFile, *speechOutFile; SKP_int32 packetSize_ms=0, API_Fs_Hz = 0; SKP_int32 decSizeBytes; void *psDec; SKP_float loss_prob; SKP_int32 frames, lost, quiet; SKP_SILK_SDK_DecControlStruct DecControl; if( argc < 3 ) { print_usage( argv ); exit( 0 ); } /* default settings */ quiet = 0; loss_prob = 0.0f; /* get arguments */ args = 1; strcpy( bitInFileName, argv[ args ] ); args++; strcpy( speechOutFileName, argv[ args ] ); args++; while( args < argc ) { if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) { sscanf( argv[ args + 1 ], "%f", &loss_prob ); args += 2; } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_API" ) == 0 ) { sscanf( argv[ args + 1 ], "%d", &API_Fs_Hz ); args += 2; } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-quiet" ) == 0 ) { quiet = 1; args++; } else { printf( "Error: unrecognized setting: %s\n\n", argv[ args ] ); print_usage( argv ); exit( 0 ); } } if( !quiet ) { printf("********** Silk Decoder (Fixed Point) v %s ********************\n", SKP_Silk_SDK_get_version()); printf("********** Compiled for %d bit cpu *******************************\n", (int)sizeof(void*) * 8 ); printf( "Input: %s\n", bitInFileName ); printf( "Output: %s\n", speechOutFileName ); } /* Open files */ bitInFile = fopen( bitInFileName, "rb" ); if( bitInFile == NULL ) { printf( "Error: could not open input file %s\n", bitInFileName ); exit( 0 ); } /* Check Silk header */ { char header_buf[ 50 ]; fread(header_buf, sizeof(char), 1, bitInFile); header_buf[ strlen( "" ) ] = '\0'; /* Terminate with a null character */ if( strcmp( header_buf, "" ) != 0 ) { counter = fread( header_buf, sizeof( char ), strlen( "!SILK_V3" ), bitInFile ); header_buf[ strlen( "!SILK_V3" ) ] = '\0'; /* Terminate with a null character */ if( strcmp( header_buf, "!SILK_V3" ) != 0 ) { /* Non-equal strings */ printf( "Error: Wrong Header %s\n", header_buf ); exit( 0 ); } } else { counter = fread( header_buf, sizeof( char ), strlen( "#!SILK_V3" ), bitInFile ); header_buf[ strlen( "#!SILK_V3" ) ] = '\0'; /* Terminate with a null character */ if( strcmp( header_buf, "#!SILK_V3" ) != 0 ) { /* Non-equal strings */ printf( "Error: Wrong Header %s\n", header_buf ); exit( 0 ); } } } speechOutFile = fopen( speechOutFileName, "wb" ); if( speechOutFile == NULL ) { printf( "Error: could not open output file %s\n", speechOutFileName ); exit( 0 ); } /* Set the samplingrate that is requested for the output */ if( API_Fs_Hz == 0 ) { DecControl.API_sampleRate = 24000; } else { DecControl.API_sampleRate = API_Fs_Hz; } /* Initialize to one frame per packet, for proper concealment before first packet arrives */ DecControl.framesPerPacket = 1; /* Create decoder */ ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if( ret ) { printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); } psDec = malloc( decSizeBytes ); /* Reset decoder */ ret = SKP_Silk_SDK_InitDecoder( psDec ); if( ret ) { printf( "\nSKP_Silk_InitDecoder returned %d", ret ); } totPackets = 0; tottime = 0; payloadEnd = payload; /* Simulate the jitter buffer holding MAX_FEC_DELAY packets */ for( i = 0; i < MAX_LBRR_DELAY; i++ ) { /* Read payload size */ counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( &nBytes, 1 ); #endif /* Read payload */ counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( ( SKP_int16 )counter < nBytes ) { break; } nBytesPerPacket[ i ] = nBytes; payloadEnd += nBytes; totPackets++; } while( 1 ) { /* Read payload size */ counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( &nBytes, 1 ); #endif if( nBytes < 0 || counter < 1 ) { break; } /* Read payload */ counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( ( SKP_int16 )counter < nBytes ) { break; } /* Simulate losses */ rand_seed = SKP_RAND( rand_seed ); if( ( ( ( float )( ( rand_seed >> 16 ) + ( 1 << 15 ) ) ) / 65535.0f >= ( loss_prob / 100.0f ) ) && ( counter > 0 ) ) { nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes; payloadEnd += nBytes; } else { nBytesPerPacket[ MAX_LBRR_DELAY ] = 0; } if( nBytesPerPacket[ 0 ] == 0 ) { /* Indicate lost packet */ lost = 1; /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */ payloadPtr = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { if( nBytesPerPacket[ i + 1 ] > 0 ) { starttime = GetHighResolutionTime(); SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC ); tottime += GetHighResolutionTime() - starttime; if( nBytesFEC > 0 ) { payloadToDec = FECpayload; nBytes = nBytesFEC; lost = 0; break; } } payloadPtr += nBytesPerPacket[ i + 1 ]; } } else { lost = 0; nBytes = nBytesPerPacket[ 0 ]; payloadToDec = payload; } /* Silk decoder */ outPtr = out; tot_len = 0; starttime = GetHighResolutionTime(); if( lost == 0 ) { /* No Loss: Decode all frames in the packet */ frames = 0; do { /* Decode 20 ms */ ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_SDK_Decode returned %d", ret ); } frames++; outPtr += len; tot_len += len; if( frames > MAX_INPUT_FRAMES ) { /* Hack for corrupt stream that could generate too many frames */ outPtr = out; tot_len = 0; frames = 0; } /* Until last 20 ms frame of packet has been decoded */ } while( DecControl.moreInternalDecoderFrames ); } else { /* Loss: Decode enough frames to cover one packet duration */ for( i = 0; i < DecControl.framesPerPacket; i++ ) { /* Generate 20 ms */ ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_Decode returned %d", ret ); } outPtr += len; tot_len += len; } } packetSize_ms = tot_len / ( DecControl.API_sampleRate / 1000 ); tottime += GetHighResolutionTime() - starttime; totPackets++; /* Write output to file */ #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( out, tot_len ); #endif fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile ); /* Update buffer */ totBytes = 0; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { totBytes += nBytesPerPacket[ i + 1 ]; } SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) ); payloadEnd -= nBytesPerPacket[ 0 ]; SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) ); if( !quiet ) { fprintf( stderr, "\rPackets decoded: %d", totPackets ); } }
/* * Open codec. */ static pj_status_t silk_codec_open(pjmedia_codec *codec, pjmedia_codec_param *attr ) { pj_status_t status; struct silk_private *silk; int id, ret = 0; unsigned i; struct silk_param params; SKP_int32 encSizeBytes, decSizeBytes, API_fs_Hz, max_internal_fs_Hz, maxBitRate; // useinbandfec: specifies that SILK in-band FEC is supported by the decoder and MAY be used during a session. // [...] If no value is specified, useinbandfec is assumed to be 1. SKP_int useInBandFEC = 1; const pj_str_t STR_FMTP_USE_INBAND_FEC = {"useinbandfec", 12}; const pj_str_t STR_FMTP_MAX_AVERAGE_BITRATE = {"maxaveragebitrate", 17}; silk = (struct silk_private*) codec->codec_data; id = silk->param_id; pj_assert(silk != NULL); pj_assert(silk->enc_ready == PJ_FALSE && silk->dec_ready == PJ_FALSE); params = silk_factory.silk_param[id]; //PJ_LOG(4, (THIS_FILE, "Open silk codec @ %d", params.clock_rate)); /* default settings */ API_fs_Hz = params.clock_rate; max_internal_fs_Hz = params.clock_rate; maxBitRate = ( params.bitrate > 0 ? params.bitrate : 0 ); /* Check fmtp params */ for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_USE_INBAND_FEC) == 0) { useInBandFEC = (pj_uint8_t) (pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); break; }else if(pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_FMTP_MAX_AVERAGE_BITRATE) == 0) { SKP_int32 remoteBitRate = (SKP_int32)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val)); if(remoteBitRate < maxBitRate || maxBitRate == 0){ maxBitRate = remoteBitRate; } } } /* Create Encoder */ ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes ); if(ret){ PJ_LOG(1, (THIS_FILE, "Unable to get encoder size : %d", ret)); return PJ_EINVAL; } silk->psEnc = pj_pool_zalloc(silk->pool, encSizeBytes); /* Reset Encoder */ ret = SKP_Silk_SDK_InitEncoder( silk->psEnc, &silk->enc ); if(ret){ PJ_LOG(1, (THIS_FILE, "Unable to init encoder : %d", ret)); return PJ_EINVAL; } /* Set Encoder parameters */ silk->enc.API_sampleRate = API_fs_Hz; silk->enc.maxInternalSampleRate = max_internal_fs_Hz; silk->enc.packetSize = ( params.packet_size_ms * API_fs_Hz ) / 1000; // TODO : our packet loss percentage is probably not always 0... // Should this be configurable? Or set to some value so that FEC works? Well ... if we can get it working... silk->enc.packetLossPercentage = 0; silk->enc.useInBandFEC = useInBandFEC; silk->enc.useDTX = 0; silk->enc.complexity = params.complexity; silk->enc.bitRate = maxBitRate; silk->enc_ready = PJ_TRUE; //Decoder /* Create decoder */ ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if(ret){ PJ_LOG(1, (THIS_FILE, "Unable to get dencoder size : %d", ret)); return PJ_EINVAL; } silk->psDec = pj_pool_zalloc(silk->pool, decSizeBytes); /* Reset decoder */ ret = SKP_Silk_SDK_InitDecoder( silk->psDec ); if(ret){ PJ_LOG(1, (THIS_FILE, "Unable to init dencoder : %d", ret)); return PJ_EINVAL; } /* Set Decoder parameters */ silk->dec.API_sampleRate = API_fs_Hz; silk->dec_ready = PJ_TRUE; return PJ_SUCCESS; }
static switch_status_t switch_silk_init(switch_codec_t *codec, switch_codec_flag_t freeswitch_flags, const switch_codec_settings_t *codec_settings) { struct silk_context *context = NULL; SKP_int useinbandfec = 0, usedtx = 0, maxaveragebitrate = 0, plpct =0; SKP_int32 encSizeBytes; SKP_int32 decSizeBytes; int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE); int decoding = (freeswitch_flags & SWITCH_CODEC_FLAG_DECODE); if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } if (codec->fmtp_in) { int x, argc; char *argv[10]; argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; switch_assert(data); while (*data == ' ') { data++; } if ((arg = strchr(data, '='))) { *arg++ = '\0'; if (!strcasecmp(data, "useinbandfec")) { if (switch_true(arg)) { useinbandfec = 1; plpct = 10;// 10% for now } } if (!strcasecmp(data, "usedtx")) { if (switch_true(arg)) { usedtx = 1; } } if (!strcasecmp(data, "maxaveragebitrate")) { maxaveragebitrate = atoi(arg); switch(codec->implementation->actual_samples_per_second) { case 8000: { if(maxaveragebitrate < 6000 || maxaveragebitrate > 20000) { maxaveragebitrate = 20000; } break; } case 12000: { if(maxaveragebitrate < 7000 || maxaveragebitrate > 25000) { maxaveragebitrate = 25000; } break; } case 16000: { if(maxaveragebitrate < 8000 || maxaveragebitrate > 30000) { maxaveragebitrate = 30000; } break; } case 24000: { if(maxaveragebitrate < 12000 || maxaveragebitrate > 40000) { maxaveragebitrate = 40000; } break; } default: /* this should never happen but 20000 is common among all rates */ maxaveragebitrate = 20000; break; } } } } } codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d", useinbandfec ? "true" : "false", usedtx ? "true" : "false", maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second); if (encoding) { if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) { return SWITCH_STATUS_FALSE; } context->enc_state = switch_core_alloc(codec->memory_pool, encSizeBytes); if (SKP_Silk_SDK_InitEncoder(context->enc_state, &context->encoder_object)) { return SWITCH_STATUS_FALSE; } context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.packetSize = codec->implementation->samples_per_packet; context->encoder_object.useInBandFEC = useinbandfec; context->encoder_object.complexity = 2; context->encoder_object.bitRate = maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second; context->encoder_object.useDTX = usedtx; context->encoder_object.packetLossPercentage = plpct;; } if (decoding) { if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) { return SWITCH_STATUS_FALSE; } context->dec_state = switch_core_alloc(codec->memory_pool, decSizeBytes); if (SKP_Silk_SDK_InitDecoder(context->dec_state)) { return SWITCH_STATUS_FALSE; } context->decoder_object.sampleRate = codec->implementation->actual_samples_per_second; } codec->private_info = context; return SWITCH_STATUS_SUCCESS; }
static int load_module(void) { SKP_int32 ret = 0;; int res = 0; char format_string[100]; char* format; char* pointer = format_string; struct ast_format format_struct; struct ast_format* format_def = &format_struct; int attr_samp_rate = 0; /* print the skype version */ ast_log(LOG_NOTICE, "SILK Version : %s\n", SKP_Silk_SDK_get_version()); /* get the encoder / decoder sizes */ ret = SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes); if (ret) { ast_log(LOG_WARNING, "SKP_Silk_SDK_Get_Encoder_size returned %d", ret); } ret = SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes); if (ret) { ast_log(LOG_WARNING, "SKP_Silk_SDK_Get_Decoder_size returned %d", ret); } /* Finish the setup of the encoders / decoders */ /* silk8 */ ast_format_set(&silk8tolin.src_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END); ast_format_set(&silk8tolin.dst_format, AST_FORMAT_SLINEAR,0); ast_format_set(&lintosilk8.src_format, AST_FORMAT_SLINEAR,0); ast_format_set(&lintosilk8.dst_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END); /* silk12 */ ast_format_set(&silk12tolin.src_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_12KHZ, AST_FORMAT_ATTR_END); ast_format_set(&silk12tolin.dst_format, AST_FORMAT_SLINEAR12,0); ast_format_set(&lintosilk12.src_format, AST_FORMAT_SLINEAR12,0); ast_format_set(&lintosilk12.dst_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_12KHZ, AST_FORMAT_ATTR_END); /* silk16 */ ast_format_set(&silk16tolin.src_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_16KHZ, AST_FORMAT_ATTR_END); ast_format_set(&silk16tolin.dst_format, AST_FORMAT_SLINEAR16,0); ast_format_set(&lintosilk16.src_format, AST_FORMAT_SLINEAR16,0); ast_format_set(&lintosilk16.dst_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_16KHZ, AST_FORMAT_ATTR_END); /* silk24 */ ast_format_set(&silk24tolin.src_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_24KHZ, AST_FORMAT_ATTR_END); ast_format_set(&silk24tolin.dst_format, AST_FORMAT_SLINEAR24,0); ast_format_set(&lintosilk24.src_format, AST_FORMAT_SLINEAR24,0); ast_format_set(&lintosilk24.dst_format, AST_FORMAT_SILK,1, SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_24KHZ, AST_FORMAT_ATTR_END); /* Get the names of the silk codecs */ ast_getformatname_multiple_byid(format_string, sizeof(format_string), AST_FORMAT_SILK); ast_log(LOG_NOTICE, "Defined silk codecs are: %s\n", format_string); while ((format = strsep(&pointer, "(|)"))){ if(strlen(format) > 0){ if((format_def = ast_getformatbyname(format, format_def))){ /* now pull out the format attributes */ ret = ast_format_get_value(format_def, SILK_ATTR_KEY_SAMP_RATE, &attr_samp_rate); if(!ret) { switch (attr_samp_rate) { case SILK_ATTR_VAL_SAMP_8KHZ: res |= ast_register_translator(&silk8tolin); res |= ast_register_translator(&lintosilk8); silk8_reg = 1; break; case SILK_ATTR_VAL_SAMP_12KHZ: res |= ast_register_translator(&silk12tolin); res |= ast_register_translator(&lintosilk12); silk12_reg = 1; break; case SILK_ATTR_VAL_SAMP_16KHZ: res |= ast_register_translator(&silk16tolin); res |= ast_register_translator(&lintosilk16); silk16_reg = 1; break; case SILK_ATTR_VAL_SAMP_24KHZ: res |= ast_register_translator(&silk24tolin); res |= ast_register_translator(&lintosilk24); silk24_reg = 1; break; } } } } } /* register the encoder / decoder */ if(res){ return AST_MODULE_LOAD_FAILURE; } return AST_MODULE_LOAD_SUCCESS; }